2010-01-21 2 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 

우리가 이미 데이터베이스에 여러 경기를 만들었다 고 가정하면, 나는 모든 관련 경쟁으로 새로운 팀을 연결하는 중첩 된 양식을 사용하고 싶습니다.

이 시점에서 나는 정말로 도움이 필요하다. (몇 시간 동안 계속 붙어있다!) 나는 내 기존 코드가 이미 잘못된 방향으로 가고 있다고 생각하지만,

보기 ... 이것은 내가 지금까지 내 노력을 게시하지 않기 때문에 내가 정말로 붙어있는 곳입니다. 사용자가 각 대회가 적절한 것인지 선택할 수 있도록 각 대회의 체크 박스 목록을 원합니다. 그렇지 않은 대회는 선택하지 않습니다. 이 일이 그래서 당신이 제공 할 수있는 올바른 방향으로 어떤 가리키는 :) 감사와

은 정말 붙어

답변

4

함께 모델에 합류의 has_and_belongs_to_many 방법은 ... 새로운 has_many 찬성되지 않습니다 : 접근 방식을 통해 . has_and_belongs_to_many 관계에 저장된 데이터를 관리하는 것은 매우 어렵습니다. Rails가 제공하는 기본 메소드가 없기 때문에 : through 메소드는 일류 모델이므로 이와 같이 조작 될 수 있습니다. 이 문제에 관련된

, 당신이 이런 식으로 해결 할 수 있습니다 : 귀하가받는 매개 변수 중 하나가되도록

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 

를가 팀 자체를 만들에 올 때, 당신은 당신의 형태를 구성한다 배열로 보냈습니다. 일반적으로이 작업은 모든 체크 박스 필드를 'competition []'과 같은 이름으로 지정하고 각 체크 박스의 값을 대회의 ID로 설정하여 수행됩니다.

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) 

'경쟁'이다 하나는 반복된다.

경쟁 목록에서 항목을 쉽게 추가 및 제거하거나 전체 목록을 다시 할당하면 레일스가이를 기반으로 새로운 관계를 파악할 수 있습니다. new 대신 update_attributes를 사용한다는 점을 제외하고는 update 메소드가 새로운 메소드와 다르게 보일 것입니다.

+2

답장을 보내 주셔서 감사합니다. 당신이 솔루션을 잘 작동하지만 양식을 만드는 방법을 알아 내는데 조금 시간이 걸렸습니다. 팀 모양이 도우미를 사용하여 생성 된 동안 경쟁 양식 부분에 대해 수동으로 확인란을 만들었습니다 : <% = check_box_tag "팀 [competition] []", 경쟁. id, @ team.competitions.include? (competition), : id => "team_competitions _ # {competition.id}"%> – aaronrussell

관련 문제