Using sequences in factory_girl_rails - can you not have a sequence call in different factories?

If you check this out - it’s in my factories.rb file:

Factories

Factory.define :article do |t|
t.association :section # ‘belongs to a section’
t.title {|x| “#{x.section.name}Article” + Factory.next(:count) }

end

(…)

Factory.define :page do |t|
t.title “Page#{Factory.next(:count)}”
t.styles “styles here”
t.body Forgery::LoremIpsum.paragraphs(5)
end

Sequences

Factory.sequence :count do |n|
n
end

daze wrote in post #969217:

If you check this out - it’s in my factories.rb file:

Factories

Factory.define :article do |t|
t.association :section # ‘belongs to a section’
t.title {|x| “#{x.section.name}Article” + Factory.next(:count) }

end

(…)

Factory.define :page do |t|
t.title “Page#{Factory.next(:count)}”

Why are you using the same sequence in two different factories?

t.styles “styles here”
t.body Forgery::LoremIpsum.paragraphs(5)
end

Sequences

Factory.sequence :count do |n|
n
end

OK. Got it. Now what’s the question?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

On Sat, Dec 18, 2010 at 2:21 PM, daze [email protected] wrote:

I get an error in the factory for :page, but not an error
for :article, regarding the sequence :count.

This suggests that I can’t call “Factory.next(:count)” in different
factories.

Is this the case? Or is there something wrong with my methodology?

Do you have your :count sequence defined in factories/factories.rb? I
have a
similar case defined in this file and it works fine:

On Dec 18, 3:25pm, David K. [email protected] wrote:

Do you have your :count sequence defined in factories/factories.rb? I have a
similar case defined in this file and it works fine:

I have everything above defined in one file: test/factories.rb. Is
that a problem?
The doc (Usage · thoughtbot/factory_bot Wiki · GitHub) says
it’s okay to put your factory-related code here…

On Dec 18, 4:51am, Marnen Laibow-Koser [email protected] wrote:

Why are you using the same sequence in two different factories?

I just want a way to number things differently for multiple
factories. I originally had a sequence called :article_title, but
then I didn’t want to make something SO similar later
with :page_title, and I all I really need is number that increments…

OK. Got it. Now what’s the question?

I get an error in the factory for :page, but not an error
for :article, regarding the sequence :count.

This suggests that I can’t call “Factory.next(:count)” in different
factories.

Is this the case? Or is there something wrong with my methodology?

On Dec 18, 8:20pm, David K. [email protected] wrote:

You are fine… I had a problem and did not know to put my code there.

What?? If I’m fine, then why isn’t the :count sequence working for
one of the factories? (read first post)

Figured it out. Here’s the summary:

If you have a sequence called :xyz and you are calling it in a
factory, YOU NEED TO HAVE BRACKETS around the Factory.next(:xyz)
call. In my case:

Factories

Factory.define :article do |t|
t.association :section # ‘belongs to a section’
t.title {|x| “Article#{Factory.next(:count)}” }
(…)
end
(…)
Factory.define :page do |t|
t.title { “Page#{Factory.next(:count)}” } # I originally
didn’t have brackets here; that’s why it didn’t work, while it did
work above!
(…)
end

Sequences

Factory.sequence :count do |n|
n
end

Hope this helps people who come across the same issue.

On Sat, Dec 18, 2010 at 7:35 PM, daze [email protected] wrote:

You are fine… I had a problem and did not know to put my code there.

On Dec 20, 11:01am, “[email protected][email protected]
wrote:

that you want to reuse and count.

\Peter

Oh! Thank you!

On Dec 20, 11:01am, “[email protected][email protected]
wrote:

that you want to reuse and count.

\Peter

Wait… what if you wanted to do this?

t.title {|x| “#{x.section.name}Article#{Factory.next(:count)}” }

So would this be a scenario in which it’s better to have a separate
sequence for “something that is more complex” - so like a sequence
called :article_title?

On Dec 19, 11:03am, daze [email protected] wrote:

(...)

end

As a note, in the case where you just want a number in a string I
prefer this syntax:

Factory.define :article do |t|
t.association :section
t.sequence(:title) {|n| “Article#{n}”}
end

That way you don’t have a sequence who’s only job is to replicate this
functionality; save those sequences for something that is more complex
that you want to reuse and count.

\Peter

Wow, that’s great - thanks for the thorough response. I guess I’ll
use the

t.sequence(:title) {|n| “Article#{n}”}

style when I can, but otherwise I’ll have to keep that :count…

Thanks again!

On Dec 20, 4:38pm, daze [email protected] wrote:

Wait… what if you wanted to do this?

t.title {|x| “#{x.section.name}Article#{Factory.next(:count)}” }

So would this be a scenario in which it’s better to have a separate
sequence for “something that is more complex” - so like a sequence
called :article_title?

The tricky part there is that you want both the sequence and the
handle to the object that you’re creating. I think that means you
can’t use the shortcut syntax I had (or at least I don’t see how), but
it also means you can’t use a Factory.sequence :foobar do … end,
because that won’t know your x object and it doesn’t look like you can
pass in a context like you can with the other Factory objects.

It seems like you have three options which are:

  1. Do something like what you’re doing, although if you need to share
    part of it you could make a sequence :article_title for
    “article_#{n}” and then do

t.title {|x| “#{x.section.name}_#{Factory.next(:article_title)}”}

  1. You could not put the x.section.name in the title; that’d be my
    first inclination as it’d seem odd if the name you have is required to
    be that, since its just for testing purposes.

  2. You could patch factory_girl’s sequence to take a context like the
    object factories. Look at
    https://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/sequence.rb;
    basically you want to override the next method to take options and
    pass them into the call in there. I’m not sure exactly how the object
    part does it, but in theory one should be able to look at that and
    emulate the appropriate stuff.