`
clark1231
  • 浏览: 247526 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Factory Girl中的关系定义

阅读更多

 

 

原文在我另外一个博客上,地址:http://caok1231.com/blog/2013/05/02/factory-girl/

这里直接拷贝过来的,就不在另外排版了。

 

 

很多时候我们都会使用 factory-girl 去构建测试数据,但如何去定义表之间的关系,特别是那种用户角色、权限之类的,接下来就稍微总结下如何用factory girl 去定义测试数据中的用户角色。

 

1.Many-to-Many

 

假定用户角色是通过many-to-many的关系定义的,比如结构是如下定义的:

class User < ActiveRecord::Base

  has_many :user_roles

  has_many :roles, :through => :user_roles

end

 

class UserRole < ActiveRecord::Base

  belongs_to :user

  belongs_to :role

end

 

class Role < ActiveRecord::Base

  attr_accessible :name

 

  has_many :user_roles

  has_many :users, :through => :user_roles

end

1.1通过seeds.rb

 

先介绍下一种简单的处理,通过加载seeds.rb,预先生成“role”

 

seeds.rb

Role.delete_all

Role.create!([{ name: 'admin' }, { name: 'member' }])

在spec_helper.rb中将其加载

 

spec_helper.rb

RSpec.configure do |config|

  .....

  config.before(:all) do

    DatabaseCleaner.start

    # execute seed.rb

    load File.expand_path('db/seeds.rb', Rails.root)

  end

  .....

end

介绍两种调用方式:

 

第一种:

factory :user do

  name "xxx"

  trait :admin do

    after(:build) {|u| u.roles << Role.find_by_name('admin') }

  end

end

 

//测试中创建admin角色的user

create :user, :admin

另外一种:

factory :user do

  name "xxx"

  trait :admin do

    after(:build) {|u| u.roles << Role.find_by_name('admin') }

  end

  factory :admin, traits: [:admin]

end

 

//测试中创建admin角色的user

create :admin

Traits 允许你组合属性,然后将它们应用到任何 factory 中。

 

1.2直接构建 many-to-many

 

上面的方法有些讨巧,实际上这个就是要解决如何通过 factory-girl 去构建 many-to-many 的关系

factory :user do

  name "xxx"

 

  factory :admin_user do

    roles {[ create(:admin_role) ]}

  end

 

  factory :member_user do

    roles {[ create(:member_role) ]}

  end

end

 

factory :role do

  factory :admin_role do

    name "admin"

  end

 

  factory :member_role do

    name "member"

  end

end

 

//测试中创建admin角色的user

create :admin_user

 

2.has-many

factory :article do

  body 'article body'

 

  factory :article_with_comment do

    after(:create) do |article|

      create(:comment, article: article)

    end

  end

end

 

factory :comment do

  body 'Great article!'

end

 

// 调用

article = create(:article_with_comment)

更多的比如多态之类的关系可以参考Factory Girl callbacks

 

3.补充

定义角色还有种更常见的方式,就是通过 Role Based Authorization 这样去定义用户角色的,可以这么处理

FactoryGirl.define do

  factory :user do

    name "xxx"

    .....

 

    # create role user for all roles

    #   

    # trait :admin do

    #   roles ["admin"]

    # end

    #   

    # factory :admin_user, :traits => [:admin]

    User::ROLES.each do |r|

      trait r do

        roles r

      end

 

      factory "#{r}_user", :traits => [r]

    end

  end

end

调用时直接这样来:

create :admin_user

 

原文在我另外一个博客上,地址:http://caok1231.com/blog/2013/05/02/factory-girl/

这里直接拷贝过来的,就不在另外排版了。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics