LoginSignup
0
0

More than 3 years have passed since last update.

【Rails】ログイン後の投稿

Last updated at Posted at 2019-07-18

ユーザのログイン後の投稿についてのメモです。

ログインしたユーザを通して、投稿記事の取得を行うイメージです。
また、モデルは1対多でいきます。
こちらの記事を参照してみてください。
https://qiita.com/kazukimatsumoto/items/14bdff681ec5ddac26d1

ユーザ(1)に対して、投稿(多)です。

全体像

モデル

Micropost(投稿)
content:string user:references

User(ユーザ)
name:string amail:string password_digest:string

コントローラ

micropostsコントローラ
toppagesコントローラ

ビュー

microposts
-無し(createとdestroy機能のみ)

toppages
-index(一覧画面に、投稿内容の表示、投稿フォーム、投稿の削除機能を取り付ける)

モデルの作成

MicropostとUserモデルを上記のカラムで作成します。

app/models/micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
end

すると、こんな感じでコードが書かれてると思います。

belongs_to :user

は、1人のUserが、多数のMicropostを投稿する場合、Micropostが、1人のUserに紐づいてますよ!と、捉えることが出来ます。
例えば、「この投稿は誰がしたの?」というときに、Micropostを通して、Userを取得することができます。

Userモデルを見てみましょう。

app/models/user.rb
class User < ApplicationRecord
  has_many :microposts
end

こちらの

has_many :microposts

は1人のUserが、多数のMicropostを投稿する場合、Userが多数のMicropostに紐づいてますよ!と捉えることができます。
例えば、「誰がこの投稿をしたの?」というときに、Userを通して、Micropostを取得することができます。Micropostは「多」なので、複数形になってます。

ルータ

次に、ルータを見ていきましょう!

config/routes.rbs
Rails.application.routes.draw do
  root to: 'toppages#index'

  resources :users, only: [:index, :show, :new, :create]

  resources :microposts, only: [:create, :destroy]
end

投稿(Microposts)機能で使用するルート情報です。
投稿の表示や、投稿画面は、投稿機能の中に入れずに、投稿機能にはcreateとdestoroyのみを持たせています。

コントローラとビュー

トップページ

app/controllers/toppages_controller.rb
class ToppagesController < ApplicationController
  def index
    if logged_in?
      @micropost = current_user.microposts.build  
      @microposts = current_user.microposts.order('created_at DESC').page(params[:page])
    end
  end
end

トップページでは、投稿の作成と、投稿の一覧の表示を行います。

@micropost = current_user.microposts.build

は、投稿機能用のコードです。current_userはrailsが提供しているメソッドで、現在ログインしているユーザを取得します。
microposts.buildは、モデルで定義したmicropostsをbuild(新規作成)するという意味です。
なので、@micropostには、現在ログイン中にユーザがmicropostsを新規作成するための箱ですよ~っていう意味です。

また、

@microposts = current_user.microposts.order('created_at DESC').page(params[:page])

は、投稿一覧用に作成してます。作成したmicropostsをorder('created_at DESC')で作成日時順に並び変えて、page(params[:page])ページメント機能(kaminari)を付けています。

では、トップページを見ていきます。

app/views/toppages/index.html.erb

<% if logged_in? %>

  <%= form_for(@micropost) do |f| %>
    <div class="form-group">
      <%= f.text_area :content, class: 'form-control', rows: 5 %>
    </div>
    <%= f.submit 'Post', class: 'btn btn-primary btn-block' %>
  <% end %>
  <p>
  <P>投稿内容</p>
  <% @microposts.each do |micropost| %>
    <div>
      <%= link_to micropost.user.name, user_path(micropost.user) %> <span class="text-muted">posted at <%= micropost.created_at %></span>
    </div>
    <div>
      <p><%= micropost.content %></p>
    </div>
  <% end %>

<% end %>

ログイン後にトップページを開くと、投稿フォームと投稿内容が表示されるようになっています。

スクリーンショット (46).png

質素ですが、トップページはこんな画面になる予定です。
(まだ投稿機能を実装していないで、投稿内容が表示されてなくても大丈夫です。)

投稿機能

投稿機能について見ていきましょう!

コントローラから見ていきます。
micropostsという名前でコントローラを作成します。投稿機能で使用するアクションは、createとdestroyのみです。

app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  before_action :correct_user, only: [:destroy]

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = 'メッセージを投稿しました。'
      redirect_to root_url
    else
      @microposts = current_user.microposts.order('created_at DESC').page(params[:page])
      flash.now[:danger] = 'メッセージの投稿に失敗しました。'
      render 'toppages/index'
    end
  end

  def destroy
    @micropost.destroy
    flash[:success] = 'メッセージを削除しました。'
    redirect_back(fallback_location: root_path)
  end

  private

  def micropost_params
    params.require(:micropost).permit(:content)
  end

  def correct_user
    @micropost = current_user.microposts.find_by(id: params[:id])
    unless @micropost
      redirect_to root_url
    end
  end
end

特に難しいところは無いかと思いますが、
投稿時に

def micropost_params
params.require(:micropost).permit(:content)
end

で、投稿内容にストロングパラメータを渡しています。
また、削除時に

before_action :correct_user, only: [:destroy]



def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
unless @micropost
redirect_to root_url
end
end

で、削除を実行するユーザが投稿したユーザかの確認を行っています。

では、トップページに削除ボタンを付けてみましょう

app/views/toppages/index.html.erb
<% if logged_in? %>

  <%= form_for(@micropost) do |f| %>
    <div class="form-group">
      <%= f.text_area :content, class: 'form-control', rows: 5 %>
    </div>
    <%= f.submit 'Post', class: 'btn btn-primary btn-block' %>
  <% end %>
  <p>
  <P>投稿内容</p>
  <% @microposts.each do |micropost| %>
    <div>
      <%= link_to micropost.user.name, user_path(micropost.user) %> <span class="text-muted">posted at <%= micropost.created_at %></span>
    </div>
    <div>
      <p><%= micropost.content %></p>
    </div>
    <div>
    <% if current_user == micropost.user %>
      <%= link_to "Delete", micropost, method: :delete, data: { confirm: "You sure?" }, class: 'btn btn-danger btn-xs' %>
    <% end %>
  </div>
  <% end %>

<% end %>

投稿も削除も出来ていますね!

スクリーンショット (47).png

まとめ

current_userで、ログイン中のユーザと投稿機能を紐づけることができました!
railsのミソの部分なんですかね。。

次は多対多の機能について投稿するので、よければ読んでってください!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0