Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为什么可以';我的工厂定义不能用另一个吗?_Ruby On Rails_Ruby_Rspec_Factory Bot_Rspec Rails - Fatal编程技术网

Ruby on rails 为什么可以';我的工厂定义不能用另一个吗?

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

我在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 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
有一个需要员工拥有角色的验证吗?如果是这样的话,这些特性怎么会对种子起作用呢?最好在你的问题中添加你的验证。