So the term ‘method_missing’ isn’t so far from what you’d think it is. I know what you’re thinking, I got 100 similar answers…. “It’s a method that’s missing”…right?
Lol, well, not precisely. You got the first part right though, method_missing is a method. But it’s an inbuilt method in Ruby’s Basic Object class. In class hierarchies, Basic Object is the the ultimate ancestor for all Ruby classes. So generally all classes inherit the method_missing method.
what is method_missing you ask?
method_missing is a method in Ruby that intercepts calls to methods that don’t exist. It handles any messages that an object can’t respond to. Let’s take the most basic example
Allow me to create a random object from an
animal class and pass it a method…
I’m telling a cow to walk,which is something it can do.So when youcreate an object
cow from the class Animal and pass it a method walk then it should respond to the method
cow = Animal.new #create a new instance called cowcow.walk #pass method walk to cow=> "I am walking!" #Returns the correct value
But let’s tell it to fly instead… Something only a ‘spider-cow’ can do…
cow.flyNoMethodError: undefined method `fly' for object:cow
Why do we get an exception? …..
Again, you’re almost right, clearly, cows don’t fly. Or can they….😯
Now instead of the
NoMethodError exception we get, I would instead like to make it clear to anyone that cows do not fly with the message, “Sorry, Cows can’t fly!”. This is where method_missing comes in handy. Method missing let’s us customize our own error messages with the concept of method overriding. This is only when we wouldn't want to get an exception.
Here’s a syntax of method missing as defined in the basic object
The method takes in 3 parameters;
m ~ This is the name of the missing method called on an object. It’s a symbol usually converted to a string before it’s used. It is a required parameter.
*args ~ This sponges up any other remaining arguments. It’s an optional parameter.
&blocks ~ This includes blocks called within the method. It’s also an optional parameter.
Now let’s implement method_missing on our own…
We now have our own class with our own method_missing. Let’s now create a cow object and call
fly on it, then see what we get…
cow = Random.new #creating a new instance of class Randomcow.fly #telling cow to fly"Sorry, cows can't fly!"
Perfect! Now everyone knows that cows can’t fly . But what now if I tell it to sing…?😃
cow.singNoMethodError: undefined method `sing' for object:cow
This is handled by the else part of our code above. When we call super, it refers us to the original method_missing on the Basic Object which has the NoMethodError.
Hence, we always have an upper hand since we can always override method_missing and write error messages that best suit our preferences.
NOTE: OVERRIDING A PARENT METHOD DOESN’T GET RID OF THE ORIGINAL, WE ONLY ALTER A COPY OF IT.
method_missing in rails -active record
The best way to understand method missing in active record is the use of
attribute based finders. These are usually methods that require a
suffix in order to be executed. Here are three common examples:
Active record is usually an intermediary between an application and the database. So as we write these methods, we give them suffixes that relate to object properties related to our current object.
For instance our cow object could have all the following attributes: name, age and price. (these are random examples, don’t take them too serious). So when we call
cow, active record takes the name suffix and compares it to columns in the database.
If any of the columns match the suffix provided, it finds the required record.
So the only time we get an exception/error is when the provided suffix does not match with any column on the database. Remember the
super thing? Yes. Now that’s method_missing for you.
Thank you 🙂