ユーザのログイン後の投稿についてのメモです。
ログインしたユーザを通して、投稿記事の取得を行うイメージです。
また、モデルは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モデルを上記のカラムで作成します。
class Micropost < ApplicationRecord
belongs_to :user
end
すると、こんな感じでコードが書かれてると思います。
belongs_to :user
は、1人のUserが、多数のMicropostを投稿する場合、Micropostが、1人のUserに紐づいてますよ!と、捉えることが出来ます。
例えば、「この投稿は誰がしたの?」というときに、Micropostを通して、Userを取得することができます。
Userモデルを見てみましょう。
class User < ApplicationRecord
has_many :microposts
end
こちらの
has_many :microposts
は1人のUserが、多数のMicropostを投稿する場合、Userが多数のMicropostに紐づいてますよ!と捉えることができます。
例えば、「誰がこの投稿をしたの?」というときに、Userを通して、Micropostを取得することができます。Micropostは「多」なので、複数形になってます。
ルータ
次に、ルータを見ていきましょう!
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のみを持たせています。
コントローラとビュー
トップページ
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)を付けています。
では、トップページを見ていきます。
<% 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 %>
ログイン後にトップページを開くと、投稿フォームと投稿内容が表示されるようになっています。
質素ですが、トップページはこんな画面になる予定です。
(まだ投稿機能を実装していないで、投稿内容が表示されてなくても大丈夫です。)
投稿機能
投稿機能について見ていきましょう!
コントローラから見ていきます。
micropostsという名前でコントローラを作成します。投稿機能で使用するアクションは、createとdestroyのみです。
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
で、削除を実行するユーザが投稿したユーザかの確認を行っています。
では、トップページに削除ボタンを付けてみましょう
<% 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 %>
投稿も削除も出来ていますね!
まとめ
current_userで、ログイン中のユーザと投稿機能を紐づけることができました!
railsのミソの部分なんですかね。。
次は多対多の機能について投稿するので、よければ読んでってください!!