Pregunta

Dado lo 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 lo intento

Factory :user

Quizás no sea sorprendente que esto dé como resultado un bucle infinito a medida que las fábricas se utilizan recursivamente entre sí para definirse a sí mismas.

Lo más sorprendente es que no he encontrado ninguna mención de cómo hacer esto en ninguna parte. ¿Existe un patrón para definir las fábricas necesarias o estoy haciendo algo fundamentalmente incorrecto?

¿Fue útil?

Solución 2

factorygirl desde entonces ha sido actualizado y ahora incluye las devoluciones de llamada para resolver este problema. Echar un vistazo a http://robots.thoughtbot.com/post / 254496652 / aint-no-cala-back-chica para obtener más información.

Otros consejos

Esta es 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 va a necesitar compañía específica puede utilizar la fábrica de esta manera

company = FactoryGirl.create(:company, #{company attributes})
user = FactoryGirl.create(:user, :companies => [company])

Esperamos que esto sea útil para alguien.

En mi opinión, basta con crear 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

Al escribir los casos de prueba para los usuarios luego simplemente escribir como este

 Factory(:user, :companies => [Factory(:company)])

La esperanza de que funcione.

no pude encontrar un ejemplo para el caso mencionado anteriormente en el sitio web proporcionado. (Sólo 1: N y Asociaciones del polimórficas, pero no HABTM). Tuve un caso similar y mi código tiene este aspecto:

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

Lo que funcionó para mí fue la creación de la asociación cuando se utiliza la fábrica. Usando su ejemplo:

user = Factory(:user)
company = Factory(:company)

company.users << user 
company.save! 
  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: Cambio de los usuarios: [usuario] para: los usuarios => [usuario] para 1.8.x rubí

Encontrados esta manera agradable y prolijo:

FactoryGirl.define do
  factory :foo do
    name "Foo" 
  end

  factory :bar do
    name "Bar"
    foos { |a| [a.association(:foo)] }
  end
end

En primer lugar os animo encarecidamente utilizar has_many: a través de lugar de HABTM (más sobre esto aquí ), por lo que va a terminar 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 usted tendrá asociación has_many en ambos lados y se puede asignar a ellos en factory_girl en la forma en que lo hizo.

Actualización para los carriles 5:

En lugar de utilizar la asociación has_and_belongs_to_many, debe tener en cuenta:. has_many :through asociación

La fábrica de usuario de esta asociación es el siguiente:

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 empresa de una manera similar.

Una vez que se ha establecido ambas fábricas, puede crear la fábrica user_with_companies con companies_count option. Aquí se puede especificar el número de empresas que el usuario pertenece a: create(:user_with_companies, companies_count: 15)

Se puede encontrar una explicación detallada sobre asociaciones Factory Girl aquí .

Se puede definir la nueva fábrica y su uso después (: crear) de devolución de llamada para crear una lista de asociaciones. Vamos a ver 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

Atributo companies_count es un 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 el número de empresas que desee:

create(:user_with_companies).companies.length # 10
create(:user_with_companies, companies_count: 15).companies.length # 15

Para HABTM utilicé rasgos y devoluciones de llamada..

Digamos que tienes los siguientes modelos:

class Catalog < ApplicationRecord
  has_and_belongs_to_many :courses
  …
end
class Course < ApplicationRecord
  …
end

Puede define la fábrica arriba:

FactoryBot.define do
  factory :catalog do
    description "Catalog description"
    …

    trait :with_courses do
      after :create do |catalog|
        courses = FactoryBot.create_list :course, 2

        catalog.courses << courses
        catalog.save
      end
    end
  end
end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top