Esta pregunta es una extensión a la planteada aquí:factorygirl en carriles - Asociaciones w/Restricciones de unicidad
Using factory_girl in Rails with associations that have unique constraints. Getting duplicate errors
La respuesta ofrecida ha funcionado perfectamente para mí. Esto es lo que parece:
# Creates a class variable for factories that should be only created once.
module FactoryGirl
class Singleton
@@singletons = {}
def self.execute(factory_key)
begin
@@singletons[factory_key] = FactoryGirl.create(factory_key)
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
# already in DB so return nil
end
@@singletons[factory_key]
end
end
end
El problema que ha surgido para mí es cuando necesito para construir manualmente una asociación para apoyar una asociación polimórfica con una restricción de unicidad en un gancho. Por ejemplo:
class Matchup < ActiveRecord::Base
belongs_to :event
belongs_to :matchupable, :polymorphic => true
validates :event_id, :uniqueness => { :scope => [:matchupable_id, :matchupable_type] }
end
class BaseballMatchup < ActiveRecord::Base
has_one :matchup, :as => :matchupable
end
FactoryGirl.define do
factory :matchup do
event { FactoryGirl::Singleton.execute(:event) }
matchupable { FactoryGirl::Singleton.execute(:baseball_matchup) }
home_team_record '10-5'
away_team_record '9-6'
end
factory :baseball_matchup do
home_pitcher 'Joe Bloe'
home_pitcher_record '21-0'
home_pitcher_era 1.92
home_pitcher_arm 'R'
away_pitcher 'Jack John'
away_pitcher_record '0-21'
away_pitcher_era 9.92
away_pitcher_arm 'R'
after_build do |bm|
bm.matchup = Factory.create(:matchup, :matchupable => bm)
end
end
end
Mi aplicación Singleton actual no admite llamar FactoryGirl::Singleton.execute(:matchup, :matchupable => bm)
, solamente FactoryGirl::Singleton.execute(:matchup)
.
¿Cómo recomendaría modificar la fábrica de singleton para admitir una llamada como FactoryGirl::Singleton.execute(:matchup, :matchupable => bm)
O FactoryGirl::Singleton.execute(:matchup)
?
Porque en este momento, el código anterior arrojará un error de validación de unicidad ("El evento ya está hecho") cada vez que se ejecute el gancho en fábrica: baseball_matchup. En última instancia, esto es lo que se debe corregir para que no haya más de un emparejamiento o baseball_matchup en el DB.
métodos
Creo que el problema aquí es que cuando llamas a FactoryGirl.create y hay un registro existente en la base de datos (por lo tanto, se genera una excepción), no se devolverá el singleton porque no estamos llamando a @@ singletons [factory_key ] después del rescate. – keruilin