Factory Girl:使用内联序列与非内联序列

发布于 2024-12-24 02:15:21 字数 619 浏览 1 评论 0原文

有(至少?)两种方法可以在工厂女孩中使用序列:

Factory.sequence :my_id do |n|
  "#{n}"
end

Factory.define :my_object do |mo|
  mo.id        Factory.next :my_id
end

以及简单地内联执行:

Factory.define :my_object do |mo|
  mo.sequence(:id)    { |n| "#{n}" }
end

我的问题是这样的。如果我在两个不同的工厂中使用内联版本,是否会出现两个不同的序列,它们都从 1 开始并串联递增……这意味着如果我创建每种类型的工厂对象之一,它们的 id 都会为 1?

如果我在两个不同的工厂中使用外部定义的序列,我能保证在两个对象之间获得唯一的 ID 吗?意思是每个对象的 id 会不同吗?

我试图确认上述行为是否准确,因为我正在使用一个完全愚蠢的数据模型,试图获取 rspec &工厂女孩玩得很开心。数据库的设计者进行了设置,以便不同的对象必须生成在一组不相关的对象中唯一的 id。尽管我真的很想将这些东西拖回到 Rails 上,但此时更改数据模型并不是一个可行的解决方案。

There are (at least?) two ways to use a sequence in factory girl:

Factory.sequence :my_id do |n|
  "#{n}"
end

Factory.define :my_object do |mo|
  mo.id        Factory.next :my_id
end

and simply doing it inline:

Factory.define :my_object do |mo|
  mo.sequence(:id)    { |n| "#{n}" }
end

My question is this. If I use the inline version in two different factories, will there be two different sequences that both start at 1 and increment in tandem...meaning that if I create one of each type of factory object they will both have id 1?

If I use the externally defined sequence in two different factories am I guaranteed to get unique ids across the two objects? Meaning will the ids of each object be different?

I am trying to confirm if the behavior above is accurate because I'm working with a completely goofy data model trying to get rspec & factory girl to play nice with it. The designer of the database set things up so that different objects have to have ids generated that are unique across a set of unrelated objects. Changing the data model at this point is not a feasible solution though I'd really love to drag this stuff back onto the Rails.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久随 2024-12-31 02:15:21

当在两个不同的工厂中使用外部定义的序列时,您将看到工厂之间的 id 递增。然而,当使用内联序列时,每个工厂都会有自己的序列。

我创建了下面的示例 rake 任务来说明这一点。它显示以下结果:

*** External FactoryGirl Sequence Test Results ***
User Name: Name 1
User Name: Name 2
User Name: Name 3
User Name: Name 4
Role: Name 5
Role: Name 6
Role: Name 7
Role: Name 8
*** Internal FactoryGirl Sequence Test Results ***
User Name: Name 1
User Name: Name 2
User Name: Name 3
User Name: Name 4
Role: Role 1
Role: Role 2
Role: Role 3
Role: Role 4

正如您所看到的,使用外部序列时,随着您从用户移动到角色,该数字会继续增加。然而,当使用内联序列时,增量是彼此独立的。

本示例使用了以下模式文件:

create_table "users", :force => true do |t|
  t.string   "name"
  t.string   "email"
end

create_table "roles", :force => true do |t|
  t.string   "name"
end

示例 rake 任务是:

require 'factory_girl_rails'
namespace :sequencetests do
  Rake::Task[:environment].invoke
  task :external do
    FactoryGirl.factories.clear
    desc "Factory Girl Sequence Test using an externally defined sequence"
    puts "*** External FactoryGirl Sequence Test Results ***"
    FactoryGirl.define do
      sequence :name do |n|
        "Name #{n}"
      end
      factory :user do |u|
        name
      end

      factory :role do |r|
        name
      end
    end

    users = buildit(:user)
    roles = buildit(:role)

    puts( showit(users, "User Name: "))
    puts( showit(roles, "Role: "))
  end

  task :inline do
    FactoryGirl.factories.clear
    puts "*** Internal FactoryGirl Sequence Test Results ***"
    desc "Factory Girl Sequence Test using an inline sequence"
    FactoryGirl.define do
      factory :user do |u|
        u.sequence(:name) {|n| "Name #{n}" }
      end

      factory :role do |r|
        r.sequence(:name) {|n| "Role #{n}" }
      end
    end

    users = buildit(:user)
    roles = buildit(:role)

    puts( showit(users, "User Name: "))
    puts( showit(roles, "Role: "))

  end

end
task sequencetests: ['sequencetests:external', 'sequencetests:inline']

def buildit(what)
  items = []
  4.times do
    items << FactoryGirl.build(what)
  end
  items
end


def showit(items, prefix = "Name: ")
  results = ""
  items.each do |item|
    results += "#{prefix}#{item.name}\n"
  end
  results
end

我希望这有助于解释在 FactoryGirl 中使用序列时的不同可能性。

When using externally defined sequences in two different factories you will see incrementing ids across the factories. However, when using inline sequences each factory will have their own sequence.

I created the example rake task below to illustrate this. It displays the following results:

*** External FactoryGirl Sequence Test Results ***
User Name: Name 1
User Name: Name 2
User Name: Name 3
User Name: Name 4
Role: Name 5
Role: Name 6
Role: Name 7
Role: Name 8
*** Internal FactoryGirl Sequence Test Results ***
User Name: Name 1
User Name: Name 2
User Name: Name 3
User Name: Name 4
Role: Role 1
Role: Role 2
Role: Role 3
Role: Role 4

As you can see, when using external sequences the number continues to increase as you move from the user to the role. However when using an inline sequence the increments are independent of each other.

The following schema files were used for this example:

create_table "users", :force => true do |t|
  t.string   "name"
  t.string   "email"
end

create_table "roles", :force => true do |t|
  t.string   "name"
end

The example rake task is:

require 'factory_girl_rails'
namespace :sequencetests do
  Rake::Task[:environment].invoke
  task :external do
    FactoryGirl.factories.clear
    desc "Factory Girl Sequence Test using an externally defined sequence"
    puts "*** External FactoryGirl Sequence Test Results ***"
    FactoryGirl.define do
      sequence :name do |n|
        "Name #{n}"
      end
      factory :user do |u|
        name
      end

      factory :role do |r|
        name
      end
    end

    users = buildit(:user)
    roles = buildit(:role)

    puts( showit(users, "User Name: "))
    puts( showit(roles, "Role: "))
  end

  task :inline do
    FactoryGirl.factories.clear
    puts "*** Internal FactoryGirl Sequence Test Results ***"
    desc "Factory Girl Sequence Test using an inline sequence"
    FactoryGirl.define do
      factory :user do |u|
        u.sequence(:name) {|n| "Name #{n}" }
      end

      factory :role do |r|
        r.sequence(:name) {|n| "Role #{n}" }
      end
    end

    users = buildit(:user)
    roles = buildit(:role)

    puts( showit(users, "User Name: "))
    puts( showit(roles, "Role: "))

  end

end
task sequencetests: ['sequencetests:external', 'sequencetests:inline']

def buildit(what)
  items = []
  4.times do
    items << FactoryGirl.build(what)
  end
  items
end


def showit(items, prefix = "Name: ")
  results = ""
  items.each do |item|
    results += "#{prefix}#{item.name}\n"
  end
  results
end

I hope this helps explain the different possibilities when using sequences in FactoryGirl.

夏雨凉 2024-12-31 02:15:21

是的,内联版本将创建 2 个独立的序列,每个序列从 1 开始

Yes, the inline versions will create 2 independent sequences, each starting at 1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文