Class methods in Ruby on Rails 3 — I'm totally lost!
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.
Ruby class methods. Is it getting called on main object?
What is hello being called on?
Whenever there isn't an explicit receiver, the receiver is self
. So the call is implicitly:
self.hello
... where self
is the class Test
, on which you have just defined the self.hello
method.
goodbye
is not found because it is defined on an instance of class Test
, not the class itself, where it's currently called.
How do I see all the methods/ properties in Object Class
#methods
is the method you want. It simply returns an array of symbols, which are all the names of the methods that object responds to.
Object.new.methods
Or more readable in irb:
puts Object.new.methods.sort.to_yaml
Or for the class methods:
Object.methods
One caveat though, some objects allow methods that won't be listed here. Anything implemented with a hook into #method_missing
won't show up. This includes a lot of ActiveRecord
methods as well as other rails objects.
But so long as nothing tricky is going on, this is the list you seem to want.
class self vs self.method with Ruby: what's better?
class << self
is good at keeping all of your class methods in the same block. If methods are being added in def self.method
form then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.
def self.method
is good at explicitly stating that a method is a class method, whereas with class << self
you have to go and find the container yourself.
Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.
why has_and_belongs_to_many adds class methods rather than instance methods?
With the error and code you gave me, that is what you are probably missing:
prod = Product.new # This is a Product instance
prod.categories << Category.new # This works
prod = Product.where(name:'x') # This returns a query (ActiveRecord::Relation)
prod.categories << Category.new # This doesn't work
prod = Product.where(name:'x').first # This is a Product instance
prod.categories << Category.new # This works
Are methods in before_save called in order?
Yes, your method calls will be executed in order. The method calls are not giving you the expected result. Without seeing more code it is impossible to find a solution.
What to call this pattern of calling a method on each object?
&: is called symbol_to_proc
And it is ruby not rails specific
Relevant link
http://pragdave.pragprog.com/pragdave/2005/11/symbolto_proc.html
RubyMonk Tracking Methods
I finally figured it out, I walked away from it yesterday till this morning. I guess fresh eyes helped.
class Dojo
@@singleton_methods_added = []
def self.singleton_methods_added
@@singleton_methods_added
end
def self.singleton_method_added(method_name)
@@singleton_methods_added << method_name
end
end
uninitialized constant - totally lost with this in Rails
Logically, you must be having CarrierWave Uploader
class defined as below:
class ImageUploader < CarrierWave::Uploader::Base
## ....
end
Notice the class name ImageUploader
with l
in lowercase.
BUT you are mounting the uploader as ImageUpLoader
(Notice L
in capital) which is causing the error uninitialized constant Listings::ImageUpLoader
.
Update the code as below:
class Listings < ActiveRecord::Base
mount_uploader :image, ImageUploader ## ImageUploader with "l" in lowercase
end
Related Topics
How to Store a Ruby Array into a File
When Trying to Generate a Model with Rails and Postgresql, the Command Hangs Without Error
Linux Cli: How to Render Arabic Text into Bitmap
Cannot Install Ruby Gems - Zlib Error
How to Extend a Class from an Initializer and Have It Reload in Development Environment
Ruby Metaprogramming, How Does Rspec's 'Should' Work
How to Use Ffmpeg on a Remote Machine via Ssh
Coping with "String Contains Null Byte" Sent from Users
How to Scroll a Web Page Using Watir
Bundle Install Tries to Use Cache File
How to Create a Dynamic Regular Expression in Ruby
Howto: Model Scope for Todays Records
Unwanted Form Parameters Being Appended to Pagination Links