2015-04-16 59 views
2

我正在编写一个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): 

回答

0

看起来像父类的模块内包含在某种程度上搞乱的方式轨是映射方法。拉出来(并重新启动客运)似乎工作:

class BankAccount < AccountModel 
    . . . 
end 

和家长:

module AccountsAPI 
    class SomeOtherClass 
    . . . 
    end 
end 

class AccountModel 
    class << self 
    def get id 
    . . 
    end 

    def update_existing options 
     . . . 
    end 
end 

看起来像它的工作原理。不知道为什么。我看过:class Child < Module::Parent之前的模式。正如我在我的帖子中暗示的那样,我错过了一些Railsy(可能是ruby)配置方面的内容。

我将其作为另一个模型(只是调用get)实际上是“SomeOtherClass”的一个实例,因此它将暴露给模块中的类。我仍然乐于接受建议!

0

看起来像Passenger是全局缓存模块,而不是在应用程序重新启动时更新它。移动两班到他们各自的脚本,在lib文件夹以及模块的声明完全工作:

# ./lib/some_other_class.rb 
class SomeOtherClass 
    . . . 
end 

# ./lib/account_model.rb 
class AccountModel 
. . . 
end 

滑轨显然这些数据映射到应用层面namspace这样的声明,如:

class MySomeOtherClassModel < SomeOtherClass 

class MyAccountModel < AccountModel 

被发现的轨道作为列入命名库通过在负载(即服务器启动)的应用确保列入