find_or_initialize_by и has_many: через - PullRequest
       0

find_or_initialize_by и has_many: через

3 голосов
/ 01 августа 2011

У меня есть XML-файл, из которого пользователь импортирует данные.Это создает запись в модели Player.В то же время я хочу, чтобы в ассоциации Membership была создана запись.

Оба из вышеупомянутых должны запускаться, только если запись еще не существует.Это сокращенная версия метода:

@player = self.players.find_or_initialize_by_name_and_archetype(name, archetype)
if @player.save
  self.memberships.create(:player_id => @player.id)
end

Теперь find_or_initialize_by работает, но Membership все еще создается для каждого игрока, в основном игнорируя условие if.

Как можноодин сделать это кратко?

Ответы [ 2 ]

2 голосов
/ 01 августа 2011

Если @player устанавливается из находки или инициализации, вызывая для нее сохранение, можно все равно вернуть истину, даже если это не новая запись - попробуйте это в консоли, найдя объект, ничего не изменяя, вызвав сохранениена нем, и вы все равно станете правдой, пока это действительный объект.

При этом, я думаю, вы хотите, чтобы ваше состояние было более похожим на

if @player.new_record? && @player.save
1 голос
/ 01 августа 2011

ИМХО, более чистым способом было бы добавить ограничение уникальности к членству, если я не знаю, кто self в вашем коде (Team?), Как этот

class Team < ActiveRecord::Base
has_many :memberships, :before_add => :validates_membership

Я бы просто молча отбросил вызов базы данных и сообщил об успехе.

def validates_membership(membership)
  raise ActiveRecord::Rollback if self.memberships.include? membership
end

ActiveRecord :: Откат захвачен изнутри, но не восстановлен.
Тогда вы можете просто позвонить по номеру self.memberships.create(:player_id => @player.id), и повторное членство не будет создано.
При желании вы можете добавить ограничение уникальности на уровне базы данных add_index :memberships, [ :team_id, :player_id ], :unique => true, :name => 'by_team_and_player.

И, наконец, что не менее важно (некоторые скажут, что вы должны сделать это в первую очередь), вы можете добавить тесты для проверки уникальности членства.

...