我有一个相当标准的博客应用程序,其中包含通常的帖子和评论控制器/模型以及用于留下评论的用户模型。
所以在用户模型中我有
has_many :comments
在评论模型中
belongs_to :post
belongs_to :user
一切都非常直截了当。
在我正在创建的应用中,我希望评论的行为略有不同。当用户第一次发表评论时,我将创建一个新评论。但是我只希望每个用户每个帖子允许一条评论。如果用户试图留下另一条评论,那么我们应该只更新现有评论。
为此,我已将此添加到用户模型
has_many :posts, :through => :comment
在Posts控制器中,我在show动作中有以下内容。
if post = current_user.posts.find_by_permalink(params[:id])
@comment = post.comments.find_by_user_id(current_user)
else
@comment = Comment.new
end
这是因为它检查用户是否已对此帖发表评论,如果是,则会导致评论更新而不是发布新评论。
但是,上面的代码并不适合我。有更优雅的解决方案吗?
答案 0 :(得分:2)
你这样做的方式很好,但你应该把逻辑移到模型中。我还建议使用validates_uniqueness_of
添加一些验证。
在邮政中你可以这样做:
has_many :comments do
def find_or_build_for_user(user)
find_by_user_id(current_user.id) || self.comment.build(:user => user)
end
end
然后在你的控制器中你会这样做:
@comment = post.comments.find_or_build_for_user(current_user)
以上使用关联扩展,您可以在这里阅读更多相关内容:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
我不确定上述内容是否会像我没有测试过一样,但它应该指向正确的方向。