2

这让我发疯了。FactoryGirl 已停止工作,但我不明白为什么或如何——也许是我进行了 gem 更新?首先是问题,然后是细节:

>>> c = FactoryGirl.create(:client)
=> #<Client id: 3, name: "name3", email: "client3@example.com", password_digest: "$2a$10$iSqct/0DIQbL.OcRrYOiPuiKijbAXggLxcMevS3TmVIV...", created_at: "2012-08-14 23:25:22", updated_at: "2012-08-14 23:25:22">
>>> a = FactoryGirl.create(:admin)
ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
        from /.../usr/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/associations/collection_association.rb:425:in `create_record'

调试打印语句告诉我 :admin 是一个 new_record?,所以我自然无法与它形成关联。这是客户端工厂。这个想法是管理员只是一个被分配了管理员权限的客户端:

FactoryGirl.define do
  factory :client do
    sequence(:name) {|n| "name#{n}"}
    sequence(:email) {|n| "client#{n}@example.com" }
    password "password"

    factory :admin do
      after_create {|admin| 
        admin.assign_admin
      }
    end

  end

end

当我在控制台中复制 FactoryGirl 正在做什么(或应该做什么)时,一切正常:

>>> a = FactoryGirl.create(:client)
=> #<Client id: 4, name: "name5", email: "client5@example.com", password_digest: "$2a$10$vFsW6VfmNMKWBifPY3vcHe6Q2.vCCLEq3RqPYRxdMo0m...", created_at: "2012-08-14 23:37:11", updated_at: "2012-08-14 23:37:11">
>>> a.assign_admin
=> #<ClientRole id: 2, client_id: 4, role: 1, created_at: "2012-08-14 23:37:28", updated_at: "2012-08-14 23:37:28">
>>> a.admin?
=> true

这是客户端模型:

class Client < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password
  validates_presence_of :name, :email, :password, :on => :create
  validates :name, :email, :uniqueness => true
  has_many :sites, :dependent => :destroy
  has_many :client_roles, :dependent => :destroy
  # roles

  def has_role?(role)
    client_roles.where(:role => role).exists?
  end

  def assign_role(role)
    client_roles.create(:role => role) unless has_role?(role)
  end

  def revoke_role(role)
    client_roles.where(:role => role).destroy_all
  end

  def assign_admin
    assign_role(ClientRole::ADMIN)
  end

  def admin?
    has_role?(ClientRole::ADMIN)
  end

end

为了完整起见,ClientRole 模型:

class ClientRole < ActiveRecord::Base
  belongs_to :client

  # values for #role
  ADMIN = 1

end

最后,来自 Gemfile.lock 的版本和依赖信息:

factory_girl (4.0.0)
  activesupport (>= 3.0.0)
factory_girl_rails (4.0.0)
  factory_girl (~> 4.0.0)
  railties (>= 3.0.0)
4

1 回答 1

9

解决了。最新版本的 FG 发生了一些变化。以下工厂方法用于工作:

factory :admin do
  after_create {|admin| 
    admin.assign_admin
  }
end

但最新的文档说现在的语法是:

factory :admin do
  after(:create) {|admin| 
    admin.assign_admin
  }
end

改变它使一切正常。

于 2012-08-15T01:49:27.157 回答