Ruby on rails 为什么可以';我的工厂定义不能用另一个吗?
我在Rails 4.2应用程序中使用RolifGem 我正在工厂使用种子数据。然而,据我所知,这不是正确的方法 我很难弄清楚如何在不必在规范文件中使用复杂的工厂调用的情况下正确地执行此操作 这是我的员工工厂:Ruby on rails 为什么可以';我的工厂定义不能用另一个吗?,ruby-on-rails,ruby,rspec,factory-bot,rspec-rails,Ruby On Rails,Ruby,Rspec,Factory Bot,Rspec Rails,我在Rails 4.2应用程序中使用RolifGem 我正在工厂使用种子数据。然而,据我所知,这不是正确的方法 我很难弄清楚如何在不必在规范文件中使用复杂的工厂调用的情况下正确地执行此操作 这是我的员工工厂: require 'faker' #Seed the database before running the tests only if in test mode #Fixes problem with rake routes running this command and deleti
require 'faker'
#Seed the database before running the tests only if in test mode
#Fixes problem with rake routes running this command and deleting out the database
Rails.application.load_seed if Rails.env.test?
FactoryGirl.define do
factory :employee do
first_name { Faker::Name.first_name}
last_name { Faker::Name.last_name}
sequence(:email) { |n| "peterjohnson#{n}@example.com" }
mobile 66816927867
bio "MyText"
address { Faker::Address.street_address}
province_state { Faker::Address.state}
country { Faker::Address.country}
postal_code { Faker::Address.postcode}
status :active
bachelor_degree "B.Sc"
password Faker::Internet.password(8)
sequence(:paypal_email) { |n| "paypal_peterJohnson#{n}@example.com" }
sequence(:skype_id) {|n| "peterjohnson_skype#{n}" }
os :mac
role_ids [Role.first.id]
trait :proofreader do
after(:create) {|employee| employee.add_role(:proofreader)}
end
trait :admin do
after(:create) {|employee| employee.add_role(:admin)}
end
trait :super_admin do
after(:create) {|employee| employee.add_role(:super_admin)}
end
end
end
我需要在员工之前创建角色,以便在员工模型中保存他们的ID
在我的应用程序中,当员工注册时,通过表单添加角色。因此,我无法在创建后为某些测试添加角色
如果我在员工工厂中创建以下角色:
factory :employee do
["proofreader", "admin", "super_admin"].each do |role|
FactoryGirl.create(:role, name: role)
end
first_name { Faker::Name.first_name}
...
FactoryGirl.define do
factory :role do
name :proofreader
end
end
我收到一个错误,告诉我它找不到名为role的工厂。它的存在如下:
factory :employee do
["proofreader", "admin", "super_admin"].each do |role|
FactoryGirl.create(:role, name: role)
end
first_name { Faker::Name.first_name}
...
FactoryGirl.define do
factory :role do
name :proofreader
end
end
以下是我的员工模型,它验证了员工必须具有角色:
class Employee < ActiveRecord::Base
# returns the full name of the employee. This code is found in a concern called name.rb
include Name
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
enum status: [:active, :vacation, :unemployed]
enum os: [:mac, :windows]
validates :first_name,
presence: true,
length: {minimum: 2}
validates :last_name,
presence: true,
length: {minimum: 2}
validates :email, email: true, presence: true, uniqueness: true
validates :paypal_email, email: true, presence: true, uniqueness: true
validates :skype_id, presence: true, uniqueness: true
validates :mobile, presence: true, numericality: true, length: {minimum: 10}
validates :address, :province_state, :country, :postal_code, :bachelor_degree, :os,:status, :role_ids, presence: true
end
class Employee
那么,我如何才能在不植入数据库的情况下创建具有角色的员工呢?您正在尝试
FactoryGirl。当factory\u girl读取:Employee
工厂定义时,创建(:role)
。:employee
工厂在employee.rb
中,:role
工厂在role.rb
(或类似的东西)中,工厂女孩可能按文件名的字母顺序读取工厂定义,因此当定义:employee
时:role
还不存在
在定义了所有工厂之后,您需要在测试运行时创建所有角色
在:employee
工厂中,更改初始化角色ID的方式
:
role_ids { [(Role.first || FactoryGirl.create(:role, name: :default)).id] }
(实际上,您应该能够设置角色
而不是角色id
,这样您就不必在默认角色上调用.id
。)
然后在trait中的回调中添加其他角色:
trait :proofreader do
after(:create) do |employee|
FactoryGirl.create :role, name: :proofreader
employee.add_role(:proofreader)
end
end
但是,假设您的角色不发生变化,除非您的应用程序代码也发生了变化,我会使用seed。这会简单得多,我不知道为什么会不正确。我在几个项目中用种子做过,效果很好。
rake routes
不应该触动你的工厂。你确定你的意思不是像rake db:reset
或rake db:seed
这样的东西吗?我同意不应该,但确实是这样。奇怪的是,它运行seeds.rb文件没有明显的原因,除了Employees.rb工厂中存在Rails.application.load_seed,这一点更为奇怪。感谢Dave提供的代码和解释。我应该更清楚为什么我不能在一些测试中这样做。原因是我有一个特性测试,它有一个表单,在这个表单中将角色显示为复选框。我需要填充这些角色,以便我可以显示复选框。我进行了验证,检查员工在保存之前必须分配角色。因此,我无法创建未分配角色的员工。如果你知道一个正确的方法,或者我现在做的还可以,那就太好了。我是一个不折不扣的人,我想可能就是这样。我想你上面展示的特质是行不通的,因为你根本无法创造员工。如果在(:build)之后而不是(:create)之后在中创建并添加一个角色,那么它是否有效?您可能需要绕过add_role
,自己将角色添加到员工中。这些特征是有效的,因为我先给数据库添加种子,否则您是对的,它们不起作用。我将尝试后,并报告回来,如果这是一种方式。我的验证需要角色_ID存在。所以我不能构建员工对象,你是说employee
有一个需要员工拥有角色的验证吗?如果是这样的话,这些特性怎么会对种子起作用呢?最好在你的问题中添加你的验证。