I've come from using Python and I'm very confused as to how the "magic" of Ruby on Rails works.
1. There are no require statements anywhere
In Python, in order to access functions from anywhere, you must import. I assume it's the same for base ruby. But when using rails, I can call hidden variables and functions, defined in other modules, without any require statements on the top of the page.
E.g. I can have a file as such:
class CartsController < ApplicationController
....
def show
begin
@cart = Cart.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to store_url, notice: 'Invalid cart'
end
end
Where logger, redirect, and the such are all not defined. Does it simply inherit from ApplicationController up some convoluted tree, or does it somehow access those namespaces through other mechanisms?
2. Using methods that don't exist
This is valid rails code
current_item = line_items.find_by_product_id(product_id)
where find_by_products_id has not been defined anywhere and yet, Rails somehow dynamically "creates" the method on the fly. Any technical insight on how this is done?
Thanks for your help!
Rails' "Magic" makes extensive use of method_missing and const_missing.
When you try and call a method that is not defined, ruby fires a call to method_missing.
This is used by libraries like ActiveRecord to implement dynamic finders.
method_missing example:
SomeModel.find_by_some_field("some_value") is not defined.
This calls SomeModel.method_missing(:find_by_some_field, "some_value").
ActiveRecord then translates this call to `SomeModel.where(:some_field => "some_value")
(for performance purposes, ActiveRecord then dynamically defines this method, so next time find_by_some_field is defined)
const_missing example:
SomeModel has not yet been required.
The Ruby interpreter calls const_missing with the param "SomeModel"
Rails follows the convention "SomeModel" should be defined in a file called some_model.rb so const_missing just tries require "some_model".
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