This is the weirdest thing ever happened to me with ruby/rails.
I have a model, Store, which has_many Balances. And I have a method that gives me the default balance based on the store’s currency.
Store model.
class Store < ActiveRecord::Base
has_many :balances, as: :balanceable, dependent: :destroy
def default_balance
#puts self.inspect <- weird part.
balances.where(currency: self.currency)[0]
end
...
end
Balance model.
class Balance < ActiveRecord::Base
belongs_to :balanceable, :polymorphic => true
...
end
Ok, so then in the Balance controller I have the show action, that will give me a specific balance or the default one.
Balance controller.
class Api::Stores::BalancesController < Api::Stores::BaseController
before_filter :load_store
# Returns a specific alert
# +URL+:: GET /api/stores/:store_id/balances/:id
def show
#puts @store.inspect <- weird part.
@balance = (params[:id] == "default") ? @store.default_balance : Balance.find(params[:id])
respond_with @balance, :api_template => :default
end
...
private
# Provides a shortcut to access the current store
def load_store
@store = Store.find(params[:store_id])
authorize! :manage, @store
end
end
Now here is where the weird part comes…
If I make a call to the show action; for example:
GET /api/stores/148/balances/default
It returns null (because the currency was set as null, and there is no Balance with null currency), and the SQL query generated is:
SELECT `balances`.* FROM `balances` WHERE `balances`.`balanceable_id` = 148 AND `balances`.`balanceable_type` = 'Store' AND `balances`.`currency` IS NULL
So I DON’T know why… it is setting the currency as NULL. BUT if in any where in that process I put
puts @store.inspect
or inside the default_balance method:
puts self.inspect
it magically works!!!.
So I don’t know why is that happening?… It seems like the store object is not getting loaded until I “inspect” it or something like that.
Thanks
OK finally after a lot of debugging, I found the reason…
In the Store model I have a method_missing method and I had it like this:
So when I was calling
self.currencyit went first to the method_missing and then returned null. What I was missing here was thesupercall.But I continue wondering why after I had called
puts @store.inspectorputs self.inspectit worked well?. I mean, why in that case thatsupercall wasn’t needed?