как сохранить данные в две модели из одной формы - PullRequest
2 голосов
/ 04 февраля 2010

У меня есть сценарий, в котором я хотел бы сохранить данные в две модели из одной формы.

В основном у меня есть player, который принадлежит многим teams. Так что в new действии players_controller я хотел бы иметь поле множественного выбора, содержащее все команды. тогда пользователь может выбрать 2 или 3 из них .. нажмите сохранить, и они будут сохранены.

player принадлежащий многим teams выполняется таблицей с именем playerizations, она содержит player_id и team_id столбцы

так что, если я хочу получить все команды, к которым принадлежит игрок. Я просто говорю player.teams

все эти отношения работают нормально. Я просто хотел бы знать, как сохранить в playerizations таблицу при создании нового player

Что у меня есть (это в основном модель лесов):

  def new
    @player = Player.new
 @teams = Team.all
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @player }
    end

вид:

<% form_for(@player) do |f| %>
  <%= f.error_messages %>
...
....
All Teams<br/>
<%= select_tag 'selected_teams[]', options_for_select(@teams.map {|t| [t.team_name, t.id]}), :multiple => true%>
      end

Могу я получить несколько подсказок, пожалуйста? Я посмотрел на Railscast по этому поводу, но не сильно помог.

1 Ответ

2 голосов
/ 04 февраля 2010

Вы описываете отношение "есть и принадлежит многим" ("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:

Подробнее о транзакциях:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...