ruby-on-rails - polimorficas - validaciones rails
Cómo crear has_and_belongs_to_many asociaciones en Factory girl (10)
Actualización para Rails 5:
En lugar de usar has_and_belongs_to_many
association, debe considerar: has_many :through
association.
La fábrica del usuario para esta asociación se ve así:
FactoryBot.define do
factory :user do
# user attributes
factory :user_with_companies do
transient do
companies_count 10 # default number
end
after(:create) do |user, evaluator|
create_list(:companies, evaluator.companies_count, user: user)
end
end
end
end
Puede crear la fábrica de la compañía de forma similar.
Una vez que ambas fábricas estén configuradas, puede crear la fábrica user_with_companies
con la companies_count option
. Aquí puede especificar a cuántas empresas pertenece el usuario: create(:user_with_companies, companies_count: 15)
Puede encontrar una explicación detallada acerca de las asociaciones de chicas de fábrica aquí .
Dado el siguiente
class User < ActiveRecord::Base
has_and_belongs_to_many :companies
end
class Company < ActiveRecord::Base
has_and_belongs_to_many :users
end
¿cómo se definen las fábricas para empresas y usuarios, incluida la asociación bidireccional? Aquí está mi intento
Factory.define :company do |f|
f.users{ |users| [users.association :company]}
end
Factory.define :user do |f|
f.companies{ |companies| [companies.association :user]}
end
ahora intento
Factory :user
Tal vez, como era de esperar, esto da como resultado un ciclo infinito, ya que las fábricas se usan recursivamente para definirse a sí mismas.
Más sorprendentemente, no he encontrado una mención de cómo hacer esto en ninguna parte, ¿hay un patrón para definir las fábricas necesarias o estoy haciendo algo fundamentalmente erróneo?
Antes que nada, te recomiendo usar has_many: through en lugar de habtm (más sobre esto here ), así que terminarás con algo como:
Employment belongs_to :users
Employment belongs_to :companies
User has_many :employments
User has_many :companies, :through => :employments
Company has_many :employments
Company has_many :users, :through => :employments
Después de esto tendrás has_many association en ambos lados y puedes asignarlos en factory_girl de la manera en que lo hiciste.
Aquí está la solución que funciona para mí.
FactoryGirl.define do
factory :company do
#company attributes
end
factory :user do
companies {[FactoryGirl.create(:company)]}
#user attributes
end
end
si necesita una compañía específica, puede usar la fábrica de esta manera
company = FactoryGirl.create(:company, #{company attributes})
user = FactoryGirl.create(:user, :companies => [company])
Espero que esto sea útil para alguien.
En mi opinión, solo crea dos fábricas diferentes como:
Factory.define :user, :class => User do |u| # Just normal attributes initialization end Factory.define :company, :class => Company do |u| # Just normal attributes initialization end
Cuando escribe los casos de prueba para el usuario, simplemente escriba así
Factory(:user, :companies => [Factory(:company)])
Espero que funcione
Encontrado de esta manera agradable y detallado:
FactoryGirl.define do
factory :foo do
name "Foo"
end
factory :bar do
name "Bar"
foos { |a| [a.association(:foo)] }
end
end
Factorygirl se ha actualizado desde entonces y ahora incluye devoluciones de llamada para resolver este problema. Eche un vistazo a http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl para obtener más información.
Lo que funcionó para mí fue establecer la asociación cuando usé la fábrica. Usando tu ejemplo:
user = Factory(:user)
company = Factory(:company)
company.users << user
company.save!
No pude encontrar un ejemplo para el caso mencionado anteriormente en el sitio web proporcionado. (Solo 1: N y asociaciones polimórficas, pero no habtm). Tuve un caso similar y mi código se ve así:
Factory.define :user do |user|
user.name "Foo Bar"
user.after_create { |u| Factory(:company, :users => [u]) }
end
Factory.define :company do |c|
c.name "Acme"
end
Puede definir una fábrica nueva y usar después de (: crear) una devolución de llamada para crear una lista de asociaciones. Veamos cómo hacerlo en este ejemplo:
FactoryBot.define do
# user factory without associated companies
factory :user do
# user attributes
factory :user_with_companies do
transient do
companies_count 10
end
after(:create) do |user, evaluator|
create_list(:companies, evaluator.companies_count, user: user)
end
end
end
end
Attribute companies_count es transitorio y está disponible en los atributos de la fábrica y en la devolución de llamada a través del evaluador. Ahora puede crear un usuario con empresas con la opción de especificar cuántas empresas desea:
create(:user_with_companies).companies.length # 10
create(:user_with_companies, companies_count: 15).companies.length # 15
factory :company_with_users, parent: :company do
ignore do
users_count 20
end
after_create do |company, evaluator|
FactoryGirl.create_list(:user, evaluator.users_count, users: [user])
end
end
Advertencia: Cambiar usuarios: [usuario] a: usuarios => [usuario] para ruby 1.8.x.