esb*_*ngo 5 ruby ruby-on-rails
这是我用ruby/rails发生的最奇怪的事情.
我有一个模型,Store,has_many Balances.我有一个方法,根据商店的货币给我默认余额.
商店模型.
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
Run Code Online (Sandbox Code Playgroud)
平衡模型.
class Balance < ActiveRecord::Base
belongs_to :balanceable, :polymorphic => true
...
end
Run Code Online (Sandbox Code Playgroud)
好的,那么在Balance控制器中我有show动作,它会给我一个特定的余额或默认值.
平衡控制器.
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
Run Code Online (Sandbox Code Playgroud)
现在这里有奇怪的部分......
如果我打电话给节目动作; 例如:
GET/api/stores/148 /余额/默认
它返回null(因为货币设置为null,并且没有使用null货币的Balance),并且生成的SQL查询是:
SELECT `balances`.* FROM `balances` WHERE `balances`.`balanceable_id` = 148 AND `balances`.`balanceable_type` = 'Store' AND `balances`.`currency` IS NULL
Run Code Online (Sandbox Code Playgroud)
所以我不知道为什么......它将货币设置为NULL.但是如果我在那个过程中的任何地方放了
把@ store.inspect放进去
或在default_balance方法内:
把self.inspect
它神奇地工作!!!
所以我不知道为什么会发生这种情况?...看起来商店对象在我" 检查 "它或类似的东西之前没有被加载.
谢谢
好吧,经过一番调试,终于找到原因了……
在Store模型中,我有一个 method_missing 方法,如下所示:
def method_missing method_name, *args
if method_name =~ /^(\w+)_togo$/
send($1, *args).where(togo: true)
elsif method_name =~ /^(\w+)_tostay$/
send($1, *args).where(tostay: true)
end
end
Run Code Online (Sandbox Code Playgroud)
因此,当我调用时,self.currency它首先转到 method_missing ,然后返回null。我在这里缺少的是电话super。
def method_missing method_name, *args
if method_name =~ /^(\w+)_togo$/
send($1, *args).where(togo: true)
elsif method_name =~ /^(\w+)_tostay$/
send($1, *args).where(tostay: true)
else
super
end
end
Run Code Online (Sandbox Code Playgroud)
但我仍然想知道为什么在我打电话之后puts @store.inspect还是puts self.inspect效果很好?我的意思是,为什么在这种情况下super不需要那个电话?
| 归档时间: |
|
| 查看次数: |
193 次 |
| 最近记录: |