Hey everybody I have a scenario here I am really trying to figure out. I am trying to build a custom blog in Rails which requires users to be signed in to leave a comment. Basically I have 3 models - Post, User, and Comment. My problem is mainly with the comment model. I am trying to have it 开发者_运维问答so that a Comment belongs_to a User and also belongs_to Post, which have many comments. I also have made the post_id and the user_id inaccessible as I do not want them to be tampered with (I want the comment to be automatically associated with the id of the post on which it was left, and I want the user to be automatically determined via session). My problem is that I am not really sure how I can create a valid comment. If I try to add a comment doing @blog.comments.build(@attr) I am ignoring the inacessible User, and of course if I try to build it through the User I am ignoring the blog.
My guess is there is a much better way to do this and I might just be approaching it wrong. Any ideas?
I assume you have this in the Comment model:
attr_accessible :content
and when you try to build a comment this happens:
@post = Post.first
@post.comments.build(:user=>current_user)
# => WARNING: Can't mass-assign protected attributes: user
So that won't work.
If you want to protect the user_id and post_id from being overwritten on an update, you could do this:
attr_accessible :content, :user_id, :post_id
attr_readonly :user_id, :post_id
@post = Post.first
@post.comments.build(:user=>current_user)
@post.save!
# sets user_id when creating
@post.user_id = 37
@post.save!
# saves, but user_id is not changed. No warning is logged.
@post.update_attributes(:user_id=>37)
# same as above
@post.update_attribute(:user_id,37)
# raises ActiveRecord::ActiveRecordError: user_id is marked as readonly
But this seems like overkill, since presumably your application would not submit a form with a user_id for an existing comment, and someone would have to code up their own form and post it to change the ID.
You could always just set the relation manually:
comment = @post.build(@attr)
comment.user = @user
comment.save
At least, I'm pretty sure that would work.
精彩评论