Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Comment to User and Post models (Ruby on Rails)

I'm new to Rails. I'm building my first app - simple blog. I have User and Post models, where each user can write many posts. Now I want to add Comment model, where each post can have many comments, and also each user can comment on any post created by any other user.
In Comment model I have

id \ body \ user_id \ post_id

columns.
Model associations:
user.rb

has_many :posts,    dependent: :destroy
has_many :comments

post.rb

has_many :comments, dependent: :destroy
belongs_to :user

comment.rb

belongs_to :user
belongs_to :post

So how do I correctly define create action in CommentsController? Thank you.

UPDATE:
routes.rb

resources :posts do
  resources :comments
end

comments_controller.rb

  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(comment_params)
    if @comment.save
      redirect_to @post
    else
      flash.now[:danger] = "error"
    end
  end

The result is

--- !ruby/hash:ActionController::Parameters
utf8: ✓
authenticity_token: rDjSn1FW3lSBlx9o/pf4yoxlg3s74SziayHdi3WAwMs=
comment: !ruby/hash:ActionController::Parameters
  body: test
action: create
controller: comments
post_id: '57'

As we can see it doesnt send user_id and works only if I delete validates :user_id, presence: true string from comment.rb

Any suggestions?

like image 509
Alexander Avatar asked Jun 28 '14 20:06

Alexander


2 Answers

In your way you should put this:

def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.create(comment_params)
  @comment.user_id = current_user.id #or whatever is you session name
  if @comment.save
    redirect_to @post
  else
    flash.now[:danger] = "error"
  end
end

And also you should remove user_id from comment_params as strong parameters . Hope this will help you .

like image 162
zauzaj Avatar answered Sep 21 '22 16:09

zauzaj


Associations

To give you a definition of what's happening here, you have to remember whenever you create a record, you are basically populating a database. Your associations are defined with foreign_keys

When you ask how to "add comments to User and Post model" - the bottom line is you don't; you add a comment to the Comment model, and can associate it with a User and Post:

#app/models/comment.rb
Class Comment < ActiveRecord::Base
    belongs_to :user
    belongs_to :post
end

This prompts Rails to look for user_id and post_id in the Comment model by default.

This means if you wanted to create a comment directly, you can associate it to either of these associations by simply populating the foreign_keys as you wish (or use Rails objects to populate them)

So when you want to save a comment, you can do this:

#app/controllers/comments_controller.rb
Class CommentsController < ApplicationController
   def create
       @comment = Comment.new(comment_params)
   end

   private

   def comment_params
        params.require(:comment).permit(:user_id, :post_id, :etc)
   end
end

Conversely, you can handle it by using standard Rails objects (as the accepted answer has specified)

like image 23
Richard Peck Avatar answered Sep 19 '22 16:09

Richard Peck