action for creating object through 3 models. rails 4

Hi all!

I have 3 models: user, post, comment

User has_many :posts, :comments
Post belongs_to :user, has_many :comments
Comments belongs_to :user, post

So for creating post i have action create

def create
@post = Post.new(post_params)

    if @post.      save
redirect_to @post
    else
      render 'new'
    end
end

Now if following the rules of relations between Post and Comment, for creating a comment i have next action in CommentController:

def create
@post = Post.find(params[:post_id])
    @comment = @post.comments.create(comment_params)
    redirect_to post_path(@post)
end

My question is: How rewrite the actions if i want create post and comment from user?

if i try to create Comment from User, i create next action (don’t know am i right?)

def create
@user = User.find(params[:user_id])
    @post = user.posts.build(post_params)
    if @post.      save
flash[:success] = "Post created!"
      redirect_to post_path
else
      flash[:errors] = "Post not created!"
      render 'new'
    end
end

How create a comment from user, that will be in relations with post? i mean comment must have user_id and post_id?

tnx 4 help

Could you show an example of what post_params contains ?

sure.

posts_controller.rb

private

def post_params

params.require(:post).permit(:title, :body)

end

class CreatePosts < ActiveRecord::Migration

def change

create_table :posts do |t|

t.string :title

t.text :body

t.integer :user_id

t.timestamps

end

end

end

comments_controller.rb

private

def comment_params

params.require(:comment).permit(:body)

end

class CreateComments < ActiveRecord::Migration

def change

create_table :comments do |t|

t.integer :body

t.integer :post_id

t.integer :user_id

t.timestamps

end

end

end

thank you

sure.

posts_controller.rb

private

def post_params

params.require(:post).permit(:title, :body)

end

class CreatePosts < ActiveRecord::Migration

def change

create_table :posts do |t|

t.string :title

t.text :body

t.integer :user_id

t.timestamps

end

end

end

comments_controller.rb

private

def comment_params

params.require(:comment).permit(:body)

end

class CreateComments < ActiveRecord::Migration

def change

create_table :comments do |t|

t.integer :body

t.integer :post_id

t.integer :user_id

t.timestamps

end

end

end

thank you

def comment_params
params(:comment).merge!(:user_id => params[:user_id])
  params.require(:comment).permit(:body, :user_id)
end

Thank you so much, brilliant solution)

I would recommend a different solution. You should not rely on an form to capture the user_id, unless the user is actually selectable from a dropdown. Yes, you could put the user_id in a hidden form field; however, that leaves it open to be changed by the user.

Rather, I would do it this way –

PostController.rb def new @post = Post.new end

def create @post = current_user.posts.create post_params end

private def post_params params.require(:post).permit(:title, :body) end

CommentsController.rb def new @post = Post.find(params[:post_id]) @comment = @post.comments.new end

def create @post = Post.find(params[:post_id]) @comment = @post.comments.new comment_params @comment.user_id = current_user.id if @comment.save redirect_to @post else render action: new end end

private def comment_params params.require(:comment).permit(:body) end

``

I hope this is helpful