Вы описываете отношение "есть и принадлежит многим" ("HABTM"), но вы не определили его в соответствии с соглашением Rails, поэтому Rails не уверен, как оно должно обновлять ваши модели.
Модель игрока должна сказать:
has_and_belongs_to_many :teams
Модель команды должна сказать:
has_and_belongs_to_many :players
Это имеет счастливый побочный эффект, который не только дает «player.teams» список связанных с игроком команд, но также и «team.players» дает список игроков в данной команде.
Ваша таблица соединения должна называться «Players_teams», потому что соглашение Rails состоит в том, чтобы использовать имя двух моделей во множественном числе и объединять их в возрастающем алфавитном порядке. Переименования вашей таблицы "playerizations" должно быть достаточно, поскольку кажется, что столбцы таблицы правильные.
Ваш выбранный код меню почти там; вам нужно что-то вроде:
select_tag(
:player_team_ids,
options_for_select( @teams.map { | t | [ t.team_name, t.id ] } ),
{
:multiple => true,
:name => 'player[team_ids][]'
}
)
Это присвоение «name», которое содержит «magic» для присвоения массива идентификаторов вашей команды. Первый параметр «select_tag» - это просто имя поля формы «player [team_ids] []» с квадратными скобками, превращенными в подчеркивания или удаленными, если в конце строки, таким образом генерируя узнаваемый и уникальный идентификатор для использования в выходной HTML.
Затем вы можете сохранить модель своего игрока или обновить его атрибуты стандартными вызовами save () или update_attributes () - нет необходимости в дополнительном коде как таковом, однако Rails сбоит при проверках. Если вы редактируете данные существующего игрока, то вызов «update_attributes» приведет к тому, что сначала будет обновлена ассоциация команд. Затем игрок обновляется; если его проверки не пройдены, изменения команды будут сохранены в любом случае. Это довольно просто исправить; оберните ваш вызов update_attributes () в транзакции и выполните откат, если update_attributes вернет false, указывая на ошибку.
success = Player.transaction do
player.update_attributes( params[ :player ] ) ) or raise ActiveRecord::Rollback
end
Значение «success» в конечном итоге будет «true» для успеха или «nil» для неудачи. Это работает, потому что исключение отката перехватывается блоком транзакции и не распространяется. Установка «success» для оцененного результата блока вместо попытки использовать локальные переменные означает, что код совместим как с Ruby 1.8, так и с Ruby 1.9.
Это необходимо только при обновлении существующих записей с отношениями HABTM. Не требуется при создании новых записей.
Весь приведенный выше код не протестирован и может содержать ошибки при печати, поэтому, пожалуйста, используйте его с осторожностью и вниманием.
Подробнее о HABTM:
Подробнее о транзакциях: