Ruby on Rails & Calling methods with Symbols Basic Question
For some reason I haven't quite gotten the hang of how Rails interacts with Ruby / figured out Ruby itself.
I'll get to the point. For example in a Ruby on Rails project you might have something like this:
class Product < ActiveRecord::Base
default_scope :order => 'title'
end
This confuses the crap out of me. I assume we are calling the method default_scope which Product inherits from the base ActiveRecord class... so that we can set some options. We pass it the symbol :order => 'title'. is :order just a hash value within the default_scope function and it is setting that hash value as 'title' ? Am I getting that correctly.
Also for example, when you start to throw basic validation in you get something like this
validates :price, :numericalcity => {:greater_than_or_equal_to => 0.01 }
I know what this does but its syntax blows my mind. First it looks like s开发者_Python百科ymbols are used for static reused string values, but here we are sending in a dynamic symbol in... where is that going? And then are we a symbol within a symbol? Is that basically a hash within a hash or what exactly is it doing? I'm just trying to trace it out within my brain to actually understand what is going on.
You are correct in assuming default_scope
being a method, which is inherited from ActiveRecord::Base. Go here to view the source code of default_scope
.
It is a method which takes an optional Hash as it's only parameter.
This,
default_scope :order => 'title'
is the same as writing it as,
default_scope( { :order => 'title' } )
In ruby if a method is defined like,
def foobar(options = {})
p options
end
But beware of a subtle difference in syntax. Above, if you leave out the ()
keeping the {}
ruby understands it as something entirely different. Ruby sees a method default_scope
which accepts a code block
as it's argument.
default_scope { # code block }
This method definition will look like,
def foobar(&block)
yield
end
To understand how ruby blocks work read this.
You can call it like,
foobar :key_1 => 'value_1', "key_2" => 'value_2'
And Ruby understands it to be,
foobar( { :key_1 => 'value_1', "key_2" => 'value_2' } )
The keys of the Hash may or may not be symbols.
As for the validation helper method for the column attribute price
,
validates :price, :numericality => { :greater_than_or_equal_to => 0.01 }
Is the same as,
validates( :price, { :numericality => { :greater_than_or_equal_to => 0.01 } } )
This is similar to a method definition like,
def validates(column_attr, options = {})
# perform validation of column_attr
end
default_scope :order => 'title'
Is a method call
default_scope( {:order => 'title'} )
Ruby allows you to omit parentheses and braces in this case.
validates :price, :numericalcity => {:greater_than_or_equal_to => 0.01 }
means
validates( :price, {:numericalcity => {:greater_than_or_equal_to => 0.01 } } )
精彩评论