Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Created November 30, 2011 18:42
Show Gist options
  • Select an option

  • Save stevenharman/1410220 to your computer and use it in GitHub Desktop.

Select an option

Save stevenharman/1410220 to your computer and use it in GitHub Desktop.
What am I missing about Ruby blocks that the following happens in factory_girl?
FactoryGirl.define do
factory :user do
sequence(:username) { |n| "bob-#{n}" }
email { |u| "#{u.username}@example.com" }
password 'password123'
# the following works:
factory :bob do username 'bob' end
# but this does not:
factory :alice { username 'alice' }
#=> syntax error, unexpected '{', expecting keyword_end
# factory :alice { username 'alice' }
# ^
end
end
@mxriverlynn
Copy link
Copy Markdown

factory :alice, {username 'alice'}

you're missing a comma between :alice and {

@stevenharman
Copy link
Copy Markdown
Author

@derickbailey, I don't think that's it either. If I recall correctly, { ... } and do ... end both define a block in this case, its just a matter of precedence - the do ... end is higher. So my guess is that it's not high enough to correctly be associated with the factory method as it's last arg.

Just to be sure, I tried the following

factory :alice, { username 'alice' }
#=> syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('
#    factory :alice, { username 'alice' }
#                                ^

@mxriverlynn
Copy link
Copy Markdown

... oh, i see... you were trying to use { } as a block, not as a hash. the reason that doesn't work is precedence of {} vs do ... end, like you said.

the precedence of { } is the previous keyword or invocation... in this case, :alice. Since :alice is not a method call, the interpreter thinks { } should be a hash, not a block.

you have two options... use do ... end for your block, or use parenthesis around the factory call: factory(:alice){ username 'alice' }

this works because the parens tells ruby which part is a param to the method call, which then allows it to realize the { } is a block, not a parameter

@objo
Copy link
Copy Markdown

objo commented Nov 30, 2011

What happens if you move the password method up? Same thing? Sounds like it is order of operations.

@stevenharman
Copy link
Copy Markdown
Author

@objo, @derickbailey
Indeed, it is an issue with the precedence and the interpreter thinking my intended block was really a hash, thus the error. I switched to explicit parens.

factory(:bob) { username 'bob' }
factory(:alice) { username 'alice' }

Thanks, all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment