前提条件
ログインしたユーザーのみがコメント/投稿できるように制限をかけてみたいと思います。
♦︎投稿機能、コメント機能、ユーザー機能が実装済みである
♦︎Gem 'devise'を導入している
上記を前提条件として記述していきます!
ポイントは"user_signed_in?"メソッド
user_signed_in?メソッドとはなんぞや。まあ読んだままのメソッドで、
ユーザーがサインインしているかどうか判定してくれます。
ヘルパーメソッドの一種ですが、こちらは前提条件で示しているように、
deviseを導入していることで使えます。
※もしuserではなくて、customerやmemberを使用している場合は
それぞれの仕様に書き換えてください。
コントローラーを書き換える
def create
if user_signed_in? ①
post = Post.find(params[:post_id])
comment = current_user.comments.new(comment_params)
comment.post_id = post.id
comment.save
redirect_to post_path(post)
else ②
flash[:notice]="ログインが必要です"
redirect_to new_user_session_path
end
end
①ここのif文を用いて条件分岐をさせることにより
ログインしているユーザーとしていないユーザーの仕様を分けます。
コメントする先の投稿を見つけてきて、current_user=ログインしているユーザーなら、
コメントidと投稿のidを紐づかせてsaveしますというコードです。
②else=もしログインしていないユーザーなら、コメントするにはログインが必要なので
redirect_to でログイン先に遷移させます。
この遷移先はそれぞれのルーティングを見てログイン先のパスを記述してください。
コメント欄のview
<%= form_with model: [post, comment], local:false do |f| %>
<%= f.text_area :content, placeholder: 'コメントをここに' %>
<%= f.submit "コメントする" %>
<% end %>
シンプルなのであくまで参考で!
この":content"はそれぞれに設定してあるカラムを参照してください。
これでこの"コメントする"ボタンを押せば、
ログインしていないユーザーはログインへのパスをコントローラーに記述したし、
ログインページに遷移されるはず!と思って試したら、
コメントはできないけれど、ログインページにも遷移されませんでした。
え、なぜだ、、?としばらく考えた結果。原因はこれでした。
before_action :authenticate_user!
コントローラーの一番上に記述していたこの一文。
このbefore_action :authenticate_user!は、コントローラーの先頭に記載することで、
そこで行われる処理はログインユーザーのみが実行可能になる、というメソッドです。
ちなみにこちらもdeviseを導入することで使えるようになるヘルパーメソッドなので、
user_signed_in?メソッドとは兄弟のような関係でしょうか?
これを記述していたことにより、ログインしていない状態だと
そもそもcreateアクションにもいかないわけです。
つまりは先ほどつらつら書いたcreateアクションの条件分岐も無かったことになり、
そのため遷移もされずコメントもされないという無の状態が生まれていました。
この"before_action :authenticate_user!"を消すと、
ログインしていない状態でコメントボタンをクリックするとログイン画面
遷移させることができました!
投稿機能編
ちなみに投稿機能の制限もこのコメント機能を参照にすれば実装できます。
def new
if user_signed_in?
@post = Post.new
else
flash[:notice]="ログインが必要です"
redirect_to new_user_session_path
end
end
私の場合は投稿しようとした時点で、ログイン画面に遷移させたいため、
newアクションに条件分岐を使用し定義しています。
<div class="postnew">
<%= link_to "投稿", new_post_path %>
<% if current_user == nil %> ①
<p>投稿には<%= link_to "ログイン", new_user_session_path %>が必要です</p>
<% end %>
</div>
①もし"current_user == nil"(ログインしているユーザーがnil=空)なら
ログインページに遷移するよう記述しています。
これで投稿機能もログインの有無で仕様を分けることができます。
※ちなみにpostsコントローラーは"before_action :authenticate_user!"メソッドを
使用しないと、編集も投稿もなんでもありになってしまい大変なので、
onlyを使用し実行可能なアクションを指定すると良いです。
before_action :authenticate_user!, only: [:edit, :update]
例えば上記のように記述すると、編集と更新はログインユーザーのみ実行可能ですが、
その他の一覧(index)や詳細(show)はログインなしでも実行可能です。
自分の機能に合った記述をするといいかと思います!