Background here.
In the above link, the following example is given:
class << self
def by_author(author)
where(:author_id => author.id)
end
end
Aside from that syntax being foreign to a beginner like me — I had always thought class methods were defined with def self.my_class_method
— where can I find documentation about class methods in Ruby on Rails?
As far as I know, class methods are always called on the class itself (MyClass.my_class_method
), but if class methods in Rails are chainable, it seems as though something else must be going on here!
Edit:
I suppose I sort of cheated by making that comment about the syntax for class methods. I'm really asking how Rails makes a class method chainable — I understand how method chaining works, but not how Rails can allow you to chain class methods without actually returning the class object itself after each "link" in the chain.
Class methods in Ruby are really just members of the singleton class, and doing class << self
involves opening the singleton class directly and adding to it, removing the need to declare it in each method definition.
This article on Ruby singletons does a good job explaining.
As far as class methods being chainable, that isn't something specific to class methods, the second method call is simply called on the object returned from the first. For example:
bar = foo.do_something.do_more
is equivalent to:
tmp = foo.do_something
bar = tmp.do_more
In Rails, this chainability is most often used for building SQL queries (e.g., with where
or order
, etc.). This is achieved because each of these methods returns an ActiveRecord Relation.
The reason
foo.scoped.my_foo_class_method
works is because of ActiveRecord::Relation#method_missing
doing the following:
elsif @klass.respond_to?(method)
scoping { @klass.send(method, *args, &block) }
Which checks if the ActiveRecord class responds to the method called, and if so, calls that.
Having class << self is also another way to define your methods so that you do not have to call "def self.my_method" or "def MyClass.my_method" for every single method that you are defining as a class method. Instead of calling
def self.my_method1 end def self.my_method2 end
class << self def my_method1 end def my_method2 end end
Cheers!
The following two bits of code are equivalent.
Using self.method
:
class Hello
def self.world
puts "Hello, World!"
end
end
Using class << self
:
class Hello
class << self
def world
puts "Hello, World!"
end
end
end
The only difference is readability, as well as the ease in refactoring.
The class << self
technique is often used when metaprogramming.
There is another thread that explains this. class << self vs self.method with Ruby: what's better?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With