2010-12-02 58 views
0

在我的Rails應用程序中,我有2個模型:post和post_translations。Rails:限制已提交值的枚舉列

class PostTranslation < ActiveRecord::Base 
    belongs_to :post 

    LANGUAGES = %w(en fr es de it) 
    validates_inclusion_of :language, :in => LANGUAGES 

end 

class Post < ActiveRecord::Base 
    has_many :post_translations 

end 

我想,以防止同一種語言翻譯被提交兩次,所以我想限制枚舉在特定POST_ID的語言欄未列出的值。
我不知道我是否應該在模型,控制器或幫手中做到這一點。
哪個是最佳做法?

在此先感謝。

回答

1

我會在類上使用一個屬性,而不是在實例上定義它。

class PostTranslation < ActiveRecord::Base 
    @@languages = %w(en fr es de it) 
    cattr_reader :languages 

    belongs_to :post 

    validates :language, :inclusion => { :in => @@languages }, 
    :uniqueness => { :scope => :post_id } 
end 

我們滿足您的只顯示沒有翻譯語言的要求,對郵政定義一個方法:

class Post < ActiveRecord::Base 
    has_many :post_translations 

    def untranslated 
    PostTranslation.languages - post_translations.map(&:language) 
    end 
end 

然後你就可以建立一個選擇菜單通過獲取後(@post = Post.find(params[:id])和填充從@post.untranslated收集。

0

將它保留在模型中是完全有效的。模型應承擔主要責任,確保輸入的數據是正確的。

對於您的特定情況,您可以使用:uniqueness驗證程序以及傳遞給它的範圍。基本上,您的驗證將確保語言是獨特特定職位的背景下

下面應該工作:

validates :language, :inclusion => { :in => LANGUAGES }, 
        :uniqueness => { :scope => :post_id } 

如果你喜歡Rails的2風格的語法,你可以使用:

validates_uniqueness_of :language, :scope => :post_id 
+0

好的,這將防止記錄被保存,但在我的選擇列表中,我仍然可以選擇所有語言:如何隱藏已提交的語言? – pasine 2010-12-02 20:25:42

+0

我認爲這需要一個列名,所以`:scope =>:post_id` – zetetic 2010-12-02 21:38:34