2010-01-21 6 views
6

का उपयोग कर मौजूदा मॉडल के साथ एक नया मॉडल कैसे संबद्ध करें has_and_belongs_to_many का उपयोग करके मेरे पास कई मॉडल के साथ दो मॉडल हैं। इसलिए जैसा:has_and_belongs_to_many

class Competition < ActiveRecord::Base 
    has_and_belongs_to_many :teams 
    accepts_nested_attributes_for :teams 
end 

class Team < ActiveRecord::Base 
    has_and_belongs_to_many :competitions 
    accepts_nested_attributes_for :competitions 
end 

अगर हम मान लेते हैं कि मैं पहले से ही डेटाबेस में कई प्रतियोगिताएं बनाया है, जब मैं एक नई टीम बनाएं, मैं एक नेस्टेड फार्म का उपयोग करने के लिए किसी भी प्रासंगिक प्रतियोगिताएं के साथ नए टीम संबद्ध करना चाहते हैं।

यह इस बिंदु पर है कि मुझे वास्तव में मदद की ज़रूरत है (इस पर घंटों तक फंस गया है!) और मुझे लगता है कि मेरा मौजूदा कोड पहले से ही गलत तरीके से चला गया है, लेकिन मैं इसे केवल इस मामले में दिखाऊंगा:

class TeamsController < ApplicationController 
    def new 
    @team = Team.new 
    @competitions.all 
    @competitions.size.times {@team.competitions.build} 
    end 
    def create 
    @team = Team.new params[:team] 
    if @team.save 
     # .. usual if logic on save 
    end 
    end 
end 

और दृश्य ... यह वह जगह है जहां मैं वास्तव में अटक गया हूं इसलिए मैं अब तक अपने प्रयासों को पोस्ट नहीं करूँगा। मैं इसे प्रत्येक प्रतिस्पर्धा के लिए चेकबॉक्स की एक सूची चाहता हूं ताकि उपयोगकर्ता यह चुन सकें कि कौन सी प्रतियोगिताओं उपयुक्त हैं, और उन लोगों को अनचेक छोड़ दें जो नहीं हैं।

मैं वास्तव में अटक कर रहा हूँ के साथ इस एक तो सही दिशा में किसी भी इशारा प्रदान कर सकते हैं :) सराहना

उत्तर

4

मॉडल एक साथ शामिल होने के has_and_belongs_to_many विधि नई has_many के पक्ष में पदावनत कर रहा है ...: दृष्टिकोण के माध्यम से । Has_and_belongs_to_many रिश्ते में संग्रहीत डेटा को प्रबंधित करना बहुत मुश्किल है, क्योंकि रेल द्वारा प्रदान की जाने वाली कोई डिफ़ॉल्ट विधि नहीं है, लेकिन: विधि के माध्यम से एक प्रथम श्रेणी का मॉडल है और इसे इस तरह से छेड़छाड़ की जा सकती है।

यह आपकी समस्या से संबंधित है के रूप में, आप इस तरह इसे हल कर सकते हैं:

class Competition < ActiveRecord::Base 
    has_many :participating_teams 
    has_many :teams, 
    :through => :participating_teams, 
    :source => :team 
end 

class Team < ActiveRecord::Base 
    has_many :participating_teams 
    has_many :competitions, 
    :through => :participating_teams, 
    :source => :competition 
end 

class ParticipatingTeam < ActiveRecord::Base 
    belongs_to :competition 
    belongs_to :team 
end 

यह टीमें खुद को बनाने की बात आती है, तो आप अपने प्रपत्र संरचना चाहिए ताकि मापदंडों आप प्राप्त में से एक है कि एक सरणी के रूप में भेजा गया। आम तौर पर यह सभी चेक-बॉक्स फ़ील्ड्स को समान नाम होने के लिए किया जाता है, जैसे कि 'प्रतियोगिताओं []' और फिर प्रतियोगिता के आईडी होने के लिए प्रत्येक चेक-बॉक्स के लिए मान सेट करें।

class TeamsController < ApplicationController 
    before_filter :build_team, :only => [ :new, :create ] 

    def new 
    @competitions = Competitions.all 
    end 

    def create 
    @team.save! 

    # .. usual if logic on save 
    rescue ActiveRecord::RecordInvalid 
    new 
    render(:action => 'new') 
    end 

protected 
    def build_team 
    # Set default empty hash if this is a new call, or a create call 
    # with missing params. 
    params[:team] ||= { } 

    # NOTE: HashWithIndifferentAccess requires keys to be deleted by String 
    # name not Symbol. 
    competition_ids = params[:team].delete('competitions') 

    @team = Team.new(params[:team]) 

    @team.competitions = Competition.find_all_by_id(competition_ids) 
    end 
end 

जाँच करने या अपने चेक-बॉक्स सूची में प्रत्येक तत्व के लिए अनियंत्रित तरह कुछ द्वारा किया जाता है की स्थिति की स्थापना:: फिर नियंत्रक कुछ इस तरह दिखेगा

checked = @team.competitions.include?(competition) 

कहाँ 'प्रतियोगिता' है एक को फिर से चालू किया जा रहा है।

आप अपनी प्रतियोगिताओं की सूची से आसानी से आइटम जोड़ और निकाल सकते हैं, या बस पूरी सूची को फिर से असाइन कर सकते हैं और रेल इसके आधार पर नए रिश्तों को समझेंगे। आपकी अपडेट विधि नई विधि से अलग नहीं दिखाई देगी, सिवाय इसके कि आप नए के बजाय update_attributes का उपयोग करेंगे।

+2

आपके उत्तर के लिए धन्यवाद (और जवाब देने के लिए कुछ दिन लेने के लिए अपॉजिज)। आप समाधान अच्छी तरह से काम करता है, हालांकि यह फ़ॉर्म बनाने के लिए काम करने के लिए मुझे थोड़ी देर लग गई। इस पर किसी और के लाभ के लिए टीम फॉर्म उत्पन्न होता है, जबकि प्रतियोगिताओं के भाग के लिए मैंने मैन्युअल रूप से चेकबॉक्स बनाए हैं: <% = check_box_tag "टीम [प्रतियोगिताओं] []", प्रतियोगिता। आईडी, @ team.competitions.include? (प्रतियोगिता),: id => "team_competitions _ # {contest.id}"%> – aaronrussell

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