In railscasts project you can see this code:
before(:each) do
login_as Factory(:user, :admin => true)
end
The corresponding definition for the function is:
Factory.define :user do |f|
f.sequence(:github_username) { |n| "foo#{n}" }
end
I can't understand how the admin parameter is passing to function, while in the function there's no word about admin parameter. Thanks
Factory.define
is not a function definition, it is a method that takes a symbol or string (in this case user) and a block that defines the factory you are making. Factory(:user, :admin => true)
makes a User
object, with admin attributes. It is not calling the code in your second snippet, it is calling Factory()
which initializes a factory, and selects one (in this case the one defined in second snippet). Then it passes options in hash form to Factory as well.
Factory
selects the :user
factory which is very generic. The option :admin=>true
just tells Factory
to set the admin instance variable on User to true.
This is actually what it is calling in factory.rb in factory girl
def initialize(name, options = {}) #:nodoc:
assert_valid_options(options)
@name = factory_name_for(name)
@options = options
@attributes = []
end
So Factory(name,options) is equivalent to Factory.new(name,options) in this code.
http://www.ruby-doc.org/core/classes/Kernel.html Notice Array and String etc have similar constructs. I am trying to figure out how they did that now.
This is all confusing even for decent Ruby programmers. I recommend strongly the book "Metaprogramming Ruby" It is probably the best book I have read in ruby and it tells you a lot about this magic stuff.