2013-06-04 46 views
4

我是新來的鐵軌,並沒有能夠找到這個東西。Rails - 如何限制用戶輸入多個記錄每個協會

在我的應用程序中,我有產品,評論,&用戶。

評論belongs_to用戶&產品,同時用戶和產品「has_many」評論。

但是,我想限制用戶輸入每個產品的多個評論(每個產品都是唯一的)。因此,如果用戶爲產品創建評論並嘗試爲同一產品撰寫另一篇評論,他們會被告知不允許他們編輯現有評論。

我的問題是:我應該在控制器級別執行此操作,還是有可能通過驗證(這看起來像是更簡單的解決方案)執行此操作?只是不知道如何處理它。

回答

9

您可以輕鬆地用模型驗證做到這一點,指數會有所幫助。但是警告,如果你在沒有附帶的ActiveRecord驗證的情況下執行唯一索引,你的保存將會失敗並導致可用性/調試頭痛。

這應做到:

class Review < ActiveRecord::Base 
    validates :user_id, :uniqueness => { :scope => :product_id, 
    :message => "Users may only write one review per product." } 
end 

如果要添加索引,試試這個在遷移:

class AddUniquenessConstraintToReviews < ActiveRecord::Migration 
    add_index :review, [:user_id, :product_id], 
    :name => "udx_reviews_on_user_and_product", :unique => true 
end 

編輯:作爲一個全職的Rails的dev的我依然請參閱the ActiveRecord docs,以便定期回顧這些內容的語法。你也應該!

+0

需要說明的是,上述驗證在「評論」模型中是否正確?添加唯一索引有什麼好處? – Zephyr4434

+0

@ Zephyr4434是的。我只是更新了答案,以澄清包含我的示例代碼的類的名稱。 –

+1

@ Zephyr4434獨特的索引將派上用場,如果你有第二個進程寫入這張表。可能的方案是後臺作業隊列或多個應用程序服務器。當我有兩個工作處理隊列同時寫同一條記錄時,我一直在被咬傷。由於缺乏唯一性索引,我最終得到了兩條記錄,即使每個單獨的Rails引擎儘管它正在寫入同類型的唯一記錄。 –

0

它更好地在審查模型中驗證。下面的方法可以被添加到驗證。[假設你有正確設置關聯]

def validate_only_one_review_per_user 
    !(@user.products.include? @product) 
end