开发者

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 } } )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜