【发布时间】:2015-04-16 16:25:36
【问题描述】:
我正在编写一个作为 API 的 Rails 应用程序。我正在绕过活动记录编写自己的超级类,该超级类负责进行 api 调用。
似乎 Rails 不喜欢父级中的某些方法名称并接受其他方法名称。当我打电话给ModelClass.parent_method 时,我得到一个NoMethodError (undefined method parent_method' for ModelClass:Class):
我的代码结构如下:
#./lib/accounts_api
module AccountsAPI
class SomeOtherClass
. . .
end
class AccountModel
class << self
#this method works without fail:
def get id
url = "path to fetch object"
response = HTTParty.get(url)
return self.new response.parsed_response
end
# this method cannot be found
def update_existing options
url = "path to update object"
response = HTTParty.put(url, :body => options)
return self.new response.parsed_response
end
end
end
然后,一个派生类:
class BankAccount < AccountsApi::AccountModel
attr_accessor :id, :customer_id, :reference
def initialize(options={})
if options.respond_to? :each
options.each do |key,val|
target = "#{key}=".to_sym
self.send(target, val) if self.respond_to?(target)
end
end
end
end
还有我的控制器,错误的来源:
class BankAccountsController < ApplicationController
#Works just fine without fail
def show
@bank_account = BankAccount.get params[:id]
respond_to do |format|
format.json { render :json => @bank_account, :status => :ok }
end
end
#Throws:
# NoMethodError (undefined method `update_existing' for BankAccount:Class):
# app/controllers/bank_accounts_controller.rb:21:in update
# without fail
def update
@bank_account = BankAccount.update_existing params[:bank_account]
respond_to do |format|
format.json { render :json => @bank_account, :status => :ok }
end
end
end
注意:为了清楚起见,我省略了方法中的一些内部结构(错误处理、验证、分配等)。
解决方法修复:
如果我将 update_existing 方法名称更改为更正式的名称,例如 put,它就可以正常工作。
还有什么奇怪的,就是没有 Stacktrace。我只是在日志中看到Rendered rescues layout 消息:
Rendered /home/eggmatters/.rvm/gems/ruby-2.1.1@my-gemset/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.6ms)
Rendered /home/eggmatters/.rvm/gems/ruby-2.1.1@my-gemset/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.7ms)
Rendered /home/eggmatters/.rvm/gems/ruby-2.1.1@my-gemset/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (7.0ms)
Rendered /home/eggmatters/.rvm/gems/ruby-2.1.1@my-gemset/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (16.6ms)
更奇怪的是,从 irb 调用方法就可以了:
> options = {:id => "23", :customer_id => "123", :reference => "update"}
> BankAccount.update_existing options
=> (:bank_account => { {:id => "23", :customer_id => "123", :reference => "update"}, :id => "23"}
所以我猜,我在搞乱 Rails 消息传递。我还猜测我的 AccountModel 父类需要从 ActiveRecord 或其他 rails lib 继承一些东西,但是,这对于我来说太奇怪了,无法研究它。
注意:AccountsAPI 模块设置为包含在我的app/initializers 目录中。
另外,我忘了说,重启Passenger和/或Apache没有任何效果。
更新:进行临时修复/解决方法。将方法名称更改为put 仍然不起作用。如果我多次重新启动乘客,我可以让它更新,但它只会工作一次或两次,然后回到问题。
更新:我也不能在子模型上调用方法。在模型中,我添加了方法:
class BankAccount < AccountsApi::AccountModel
. . .
def self.update_wrapper options
return self.update options
end
. . .
end
现在抛出:
NoMethodError (undefined method `update_wrapper' for BankAccount:Class):
【问题讨论】:
标签: ruby-on-rails-4