1,rails g model comment content:text post:references user:referencesでcommentモデル作成。そのあとrails db:migrate
referencesによって、user_idやpost_idが使えるようになっている
schema.rb
create_table "comments", force: :cascade do |t|
t.text "content"
t.integer "post_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["post_id"], name: "index_comments_on_post_id" ←これ
t.index ["user_id"], name: "index_comments_on_user_id" ←これ
end
2、referencesでmodel/comment.rbにはbelongs_to :postとbelongs_to :userが追加されてるので、アソシエーションを各モデルに追加.
model/comment.rb
belongs_to :post
belongs_to :user
model/user.rb
has_many:posts
has_many:comments
model/post.rb
belongs_to:user
has_many:comments
3,routes.rbでpostsにcommentsをネストさせる
routes.rb
resources :posts do
resources :comments
end
4,rails g controller commentsでコメントコントローラー作成
5,ログインしているユーザーだけがコメントできるようにbefore_action :authenticate_user!を設定。
コメントを投稿するformを作成。
comment.controller
before_action :authenticate_user!
def create
@post = Post.find(params[:post_id])
@comment = Comment.create(params[:comment].permit(:content))
@comment.user_id = current_user.id ←これ
@comment.post_id = @post.id ←これ
#この二つが必要なのは、@comment.saveする時に、commentテーブルのカラム全てが埋まっている必要があるから(?)
(ここの認識が自信ありません。わかる人いたら教えてください。お願いします。)
if @comment.save
redirect_to post_path(@post)
else
render "new"
end
もしくは、(多分これでも大丈夫。挙動に変化はなし。これもわかる人いたら教えてください。お願いします。)
comment.controller
before_action :authenticate_user!
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment].permit(:content))
@comment.user_id = current_user.id
if @comment.save
redirect_to post_path(@post)
else
render "new"
end
end
のいずれか。
そしてフォーム。
comments/_form.html.erb
<%= form_for([@post,@post.comments.build]) do |f| %>
<p>content:<%= f.text_field :content %></p>
<p><%= f.button :submit %></p>
<% end %>
6,posts/show.html.erb内にコメント数、コメント一覧、コメントフォーム、を作成。
posts/show.html.erb
<h1>
<p>コメント数:<%= @post.comments.count %></p>
<p>
<% @comments.each do |comment| %><br/>
投稿者:<%= comment.user.name %><br/>
コメント:<%= comment.content %>
<% end %>
</p>
<p>新規コメント:<%= render "comments/form" %></p>
</h1>
7、posts/show.html.erb内で@commentsを使っているので、postコントローラーで@commentsを定義。
posts/controller.rb
#Commentに紐づいているpostを参照してくれる。
def show
@comments = Comment.where(post_id: @post)
end