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_missingandconst_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
ActiveRecordto 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_fieldis defined)const_missing example:
SomeModelhas not yet been required.The Ruby interpreter calls
const_missingwith the param"SomeModel“Rails follows the convention
"SomeModel"should be defined in a file calledsome_model.rbsoconst_missingjust triesrequire "some_model".