Compte tenu de ce qui suit
class User < ActiveRecord::Base
has_and_belongs_to_many :companies
end
class Company < ActiveRecord::Base
has_and_belongs_to_many :users
end
comment définissez-vous les usines pour les entreprises et les utilisateurs, y compris l'association bidirectionnelle? Voici ma tentative
Factory.define :company do |f|
f.users{ |users| [users.association :company]}
end
Factory.define :user do |f|
f.companies{ |companies| [companies.association :user]}
end
maintenant j'essaye
Factory :user
Peut-être sans surprise, cela aboutit à une boucle infinie puisque les usines s’utilisent de manière récursive pour se définir.
Plus surprenant, je n’ai pas trouvé la moindre explication sur la manière de procéder, y at-il un modèle pour définir les usines nécessaires ou je fais quelque chose de fondamentalement faux?
Depuis, Factorygirl a été mis à jour et inclut désormais des rappels pour résoudre ce problème. Jetez un coup d'oeil à http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl pour plus d'informations.
Voici la solution qui fonctionne pour moi.
FactoryGirl.define do
factory :company do
#company attributes
end
factory :user do
companies {[FactoryGirl.create(:company)]}
#user attributes
end
end
si vous avez besoin d'une compagnie spécifique, vous pouvez utiliser l'usine de cette façon
company = FactoryGirl.create(:company, #{company attributes})
user = FactoryGirl.create(:user, :companies => [company])
J'espère que cela sera utile à quelqu'un.
À mon avis, il suffit de créer deux usines différentes comme:
Factory.define: utilisateur,: classe => utilisateur do | u | # Initialisation normale des attributs fin Factory.define: société,: classe => société do | u | # Initialisation normale des attributs fin
Lorsque vous écrivez les cas de test pour l'utilisateur, écrivez simplement comme ceci
Usine (: utilisateur,: entreprises => [Usine (: entreprise)])
J'espère que ça va marcher.
Je n'ai pas trouvé d'exemple pour le cas mentionné ci-dessus sur le site Web fourni. (Seulement 1: N et associations polymorphes, mais pas d'habtm). J'ai eu un cas similaire et mon code ressemble à ceci:
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
Ce qui a fonctionné pour moi, c’était de définir l’association lors de l’utilisation de l’usine. En utilisant votre exemple:
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
Attention: Modifier les utilisateurs: [utilisateur] en: utilisateurs => [utilisateur] pour Ruby 1.8.x
Trouvé ainsi Nice et verbeux:
FactoryGirl.define do
factory :foo do
name "Foo"
end
factory :bar do
name "Bar"
foos { |a| [a.association(:foo)] }
end
end
Mise à jour pour Rails 5:
Au lieu d'utiliser l'association has_and_belongs_to_many
, vous devriez envisager: l'association has_many :through
.
La fabrique d'utilisateurs pour cette association ressemble à ceci:
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
Vous pouvez créer l’usine de la société de la même manière.
Une fois les deux usines définies, vous pouvez créer une usine user_with_companies
avec companies_count option
. Ici, vous pouvez spécifier le nombre de sociétés auxquelles l'utilisateur appartient: create(:user_with_companies, companies_count: 15)
Vous pouvez trouver des explications détaillées sur les associations de filles dans les usines ici .
Pour HABTM, j’ai utilisé des traits et des rappels .
Disons que vous avez les modèles suivants:
class Catalog < ApplicationRecord
has_and_belongs_to_many :courses
…
end
class Course < ApplicationRecord
…
end
Vous pouvez définir l’usine ci-dessus :
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
Tout d'abord, je vous encourage fortement à utiliser has_many: through au lieu de habtm (pour en savoir plus sur ce ici ), vous obtiendrez ainsi quelque chose du genre
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
Après cela, vous aurez beaucoup d'associations des deux côtés et vous pourrez les affecter à factory_girl de la manière que vous avez utilisée.
Vous pouvez définir une nouvelle fabrique et utiliser après le rappel (: create) pour créer une liste d'associations. Voyons comment faire dans cet exemple:
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
L'attribut companies_count est transitoire et disponible dans les attributs de la fabrique et dans le rappel via l'évaluateur. Maintenant, vous pouvez créer un utilisateur avec des sociétés avec la possibilité de spécifier le nombre de sociétés que vous souhaitez:
create(:user_with_companies).companies.length # 10
create(:user_with_companies, companies_count: 15).companies.length # 15