Как связать новую модель с существующими моделями с помощью 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

И представление..., которое это - то, где я действительно застреваю так, я не буду обе регистрации моих усилий до сих пор. Что я хотел бы его список флажков для каждой конкуренции так, чтобы пользователь мог просто выбрать, какие Соревнования являются соответствующими, и отпуск снял флажок с теми, которые не являются.

Я действительно застреваю с этим, так цените любое указание в правильном направлении, которое можно обеспечить :)

6
задан Jon B 6 May 2011 в 13:19
поделиться

1 ответ

Способ присоединения к моделям соединения амортизируется в пользу новых 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 вместо новых.

4
ответ дан 17 December 2019 в 07:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: