2009-11-19 56 views
0

我有一個相當標準的博客應用程序,其中包含通常的發佈和評論控制器/模型以及用於留下評論的用戶模型。在rails博客應用程序中更新評論的最優雅的方式

所以在用戶模式,我有

has_many :comments 

而且在評論模型

belongs_to :post 
belongs_to :user 

一切都非常簡單。

在我創建的應用程序中,我希望評論的行爲有點不同。當用戶第一次留言時,我會創建一個新評論。不過,我只想爲每位用戶發佈一條評論。如果用戶試圖留下另一條評論,那麼我們應該只更新現有評論。

要做到這一點,我已經加了這個用戶模型

has_many :posts, :through => :comment 

而在帖子控制器我在表演的動作如下。

if post = current_user.posts.find_by_permalink(params[:id]) 
    @comment = post.comments.find_by_user_id(current_user) 
else 
    @comment = Comment.new 
end 

這工作,因爲它會檢查,如果用戶已經做出了評論這篇文章,如果是的話那麼就會導致一個更新的評論,而不是一個新的發佈。

但是,上面的代碼並不適合我。有沒有更優雅的解決方案?

+1

通過「更新現有評論」,你是指用新內容替換評論的內容,還是將兩者合併在一起? – 2009-11-19 20:43:06

回答

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

我不確定上述是否會像我一樣工作沒有經過測試,但它應該指向正確的方向。

+0

這很完美。我從來不知道關聯擴展,非常有用。謝謝。 – KJF 2009-11-19 22:45:45

+0

它們可能非常有用,但不要過度使用它們。您也可以將它們放在單獨的模塊中,並使用關聯中的:extend選項。請記住保持你的控制器瘦,你的模型胖! (http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model)。 – jonnii 2009-11-19 22:56:19

相關問題