2010-12-02 6 views
0

In meiner Rails App habe ich 2 Modelle: post und post_translations.Rails: limit Enumspalte für bereits übergebene Werte

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 

Ich möchte aus den gleichen sprachlichen Übersetzung verhindern zweimal vorgelegt werden, so möchte ich die Aufzählungen auf die Werte begrenzen, nicht in der Sprache Spalte eines bestimmten post_id aufgeführt.
Ich weiß nicht, ob ich das in Model, Controller oder Helfer tun sollte.
Welches ist die beste Vorgehensweise?

Vielen Dank im Voraus.

Antwort

1

Ich würde ein Attribut für die Klasse verwenden, anstatt es für eine Instanz zu definieren.

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 

Jetzt ist Ihre Anforderung zeigt nur die Sprachen ohne Übersetzungen zu erfüllen, wird ein Verfahren zum Post definieren:

class Post < ActiveRecord::Base 
    has_many :post_translations 

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

Dann können Sie ein Auswahlmenü erstellen, indem Sie einen Beitrag bekommen (@post = Post.find(params[:id]) und bevölkern die Sammlung von @post.untranslated.

+0

wow! das funktioniert! – pasine

0

Es ist durchaus zulässig, dies im Modell zu behalten. Modelle sollten in erster Linie dafür verantwortlich sein, dass die eingegebenen Daten korrekt sind.

Für Ihren speziellen Fall können Sie den Validator :uniqueness mit einem Gültigkeitsbereich verwenden, der an ihn übergeben wurde. Grundsätzlich Ihre Validierung stellt sicher, dass Sprachen sind einzigartig im Rahmen eines bestimmten Beitrag

Folgendes sollte funktionieren:

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

Wenn Sie die Rails 2 Stil Syntax bevorzugen, können Sie verwenden:

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

ok, dies wird verhindern, dass der Datensatz gespeichert wird, aber in meiner Auswahlliste kann ich immer noch alle Sprachen auswählen: Wie kann ich die bereits eingereichten Sprachen ausblenden? – pasine

+0

Ich denke, das braucht einen Spaltennamen, also ': scope =>: post_id' – zetetic

+0

notme, ich denke, Sie könnten wahrscheinlich etwas in einem Helfer tun wie' LANGUAGES - @ post.post_translations.all.map {| pt | pt.language} '. –