我正在编写一个Rails应用程序,它是一个API。我正在绕过活跃的记录写我自己的超级类,它负责进行API调用。 似乎Rails不喜欢父级中的某些方法名称并接受其他方法名称。当我打电话ModelClass.parent_method
,我得到一个NoMethodError (undefined method parent_method' for ModelClass:Class):
我的代码的结构是这样的:Rails无法识别继承类方法
#./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
方法名称的东西更railsy,像put
,它工作得很好。
还有什么奇怪的是,没有Stacktrace。我只是看到Rendered rescues layout
消息在日志中:
Rendered /home/eggmatters/.rvm/gems/[email protected]/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.6ms)
Rendered /home/eggmatters/.rvm/gems/[email protected]/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.7ms)
Rendered /home/eggmatters/.rvm/gems/[email protected]/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (7.0ms)
Rendered /home/eggmatters/.rvm/gems/[email protected]/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
目录中。
此外,我忘了提及,重新启动乘客和或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):