14

मैं दो मॉडल हैं: Project और ProjectDiscipline:रेल 3: कम से कम एक संघ आइटम के माध्यम से कई है की उपस्थिति को मान्य

class Project < ActiveRecord::Base 
    has_many :project_disciplinizations, :dependent => :destroy 
    has_many :project_disciplines, through: :project_disciplinizations 
    attr_accessible :project_discipline_ids 
    attr_accessible :project_disciplines_attributes 
    accepts_nested_attributes_for :project_disciplines, :reject_if => proc { |attributes| attributes['name'].blank? } 
end 

class ProjectDiscipline < ActiveRecord::Base 
    attr_accessible :name 
    has_many :project_disciplinizations, :dependent => :destroy 
    has_many :projects, through: :project_disciplinizations 
end 

class ProjectDisciplinization < ActiveRecord::Base 
    attr_accessible :project_discipline_id, :project_id 
    belongs_to :project_discipline 
    belongs_to :project 
end 

नई/संपादन Project प्रपत्र पर, मैं विषयों और एक जांच की एक सूची है उनमें से तो उन विषयों चुन सकते हैं हर एक के लिए बॉक्स:

<div class="control-group"> 
    <label class="control-label">Check disciplines that apply</label> 
    <div class="controls"> 
    <%= f.collection_check_boxes(:project_discipline_ids, ProjectDiscipline.order('name'), :id, :name, {}, {:class => 'checkbox'}) {|input| input.label(:class => 'checkbox') { input.check_box + input.text }} %> 
    <p class="help-block">You must choose at least one discipline.</p> 
    </div> 
</div> 

मैं आवश्यक है कि कम से कम एक अनुशासन चेक किया गया है एक सत्यापन जोड़ना चाहते हैं। मैंने कोशिश की है लेकिन मुझे अभी तक पता नहीं चला है। मैं यह सत्यापन कैसे जोड़ सकता हूं?

उत्तर

15

आपके मॉडल की संरचना के आधार पर उत्तर से पहले साइड नोट मैं इस स्पष्ट लिंकिंग मॉडल का उपयोग करने के बजाय has_and_belongs_to_many का उपयोग करूंगा क्योंकि ऐसा लगता है कि लिंकिंग मॉडल मूल्य के कुछ भी नहीं जोड़ता है।

हालांकि किसी भी तरह से, जवाब वही है, जो कस्टम सत्यापन का उपयोग करना है। इस पर निर्भर करता है कि क्या आप चीजों के साथ जाते हैं या जिस तरह से हैं, वे हैं______________________________________________________________________________________________________________________________________

class Project < ActiveRecord::Base 
    validates :disciplines, presence: true 
end 

इस कोड को पूरी तरह से कोड के रूप में ही कार्य करें:

validate :has_project_disciplines 

def has_project_disciplines 
    errors.add(:base, 'must add at least one discipline') if self.project_disciplinizations.blank? 
end 

या has_and_belongs_to_many

validate :has_project_disciplines 

def has_project_disciplines 
    errors.add(:base, 'must add at least one discipline') if self.project_disciplines.blank? 
end 
+0

क्या आप मेरे उत्तर की समीक्षा कर सकते हैं? – asiniy

+0

यदि आप बाद में अनुशासन को नष्ट करते हैं, तो ऐसा हो सकता है कि किसी परियोजना के पास अब कोई विषय नहीं है और इस प्रकार एक अमान्य स्थिति में है। – wacha

+1

'.empty? 'यहां अधिक उपयुक्त होगा, रिक्त प्रश्न डीबी से रिकॉर्ड लौटाते हैं, खाली' प्रोजेक्ट_डिस्प्लिंस 'से' 1 चुनें 'और' project_disciplines '.'id' = 1 LIMIT 1', जो थोड़ा सा है अधिक कुशल। –

3

आप अपनी खुद की सत्यापनकर्ता लिख ​​सकते हैं के साथ

class Project < ActiveRecord::Base 

    validate :at_least_one_discipline 

    private 
    def at_least_one_discipline 
    # Check that at least one exists after items have been de-selected 
    unless disciplines.detect {|d| !d.marked_for_destruction? } 
     errors.add(:disciplines, "must have at least one discipline") 
    end 
    end 
end 
+0

क्या आप मेरे उत्तर की समीक्षा कर सकते हैं? – asiniy

11

मैं सरल तरीका पसंद करते हैं जॉन नेगल द्वारा या validates_presence_ofblank? विधि का शोषण करने के कारण एलेक्स पेचेई भी।

+2

हां, लेकिन इस पर निर्भर है कि आपका फॉर्म कैसे स्थापित किया गया है, शायद त्रुटि की रिपोर्ट करने के लिए एक बहुत अच्छी जगह नहीं है, जो कि अनुशासन संघ (जो मौजूद नहीं है) से जुड़ी होगी। अन्य दृष्टिकोण त्रुटि को जोड़ते हैं: आधार, जो शायद अधिक उपयुक्त है। – KenB

संबंधित मुद्दे