2012-10-26 30 views
1

我需要为现有模型添加一组泛型方法。我发现这个教程:关注ActiveSupport :: Concern

http://chris-schmitz.com/extending-activemodel-via-activesupportconcern/

这在我看来就是我的目标在(我希望能有将被添加到模型中一些方法给它添加一个模块 - 一个排序混入)。

现在,即使我做普通的复制粘贴从教程中,我在下面的错误来袭(没有进一步的说明):

undefined method `key?' for nil:NilClass 

这里是我的模型看起来像:

class Folder < ActiveRecord::Base 
    attr_accessible :name, :parent_id 

    has_default 

    validates :name, presence: true 
end 

那一刻我删除has_default一切都恢复了正常

+0

你的哪个模块包含ActiveSupport :: Concern? – Yanhao

+0

扩展ActiveSupport :: Concern的是基于我的项目中的/ lib库。 – Ruslan

回答

4

检查agains你的代码...

的模块结构可能看起来像这样(从我的项目,那肯定工作的一个考虑):

# lib/taggable.rb 

require 'active_support/concern' 

module Taggable 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def taggable 
     include TaggableMethods # includes the instance methods specified in the TaggableMethods module 
     # class methods, validations and other class stuff... 
    end 
    end 

    module TaggableMethods 
    # instance methods... 
    end 
end 

现在缺少的是,你应该告诉Rails从lib目录加载模块:

# config/application.rb 

module AppName 
    class Application < Rails::Application 
    # Custom directories with classes and modules you want to be autoloadable. 
    # config.autoload_paths += %W(#{config.root}/extras) 
    config.autoload_paths += %W(#{config.root}/lib) 

    # rest ommited... 

现在模块应该包括在内。

# model.rb 

class Model 
    taggable 

end 

这是基本插件的工作原理。在您的问题中提到的教程的作者编写了一个插件,该插件仅针对从ActiveRecord::Base继承的模型,因为他正在使用其特定方法(例如update_column)。

如果你的模块不依赖于ActiveRecord方法,则不需要扩展它(该模块也可以被Mongoid模型使用)。但是,这绝对是的正确方法:

class ActiveRecord::Base 
    include HasDefault 
end 

如果你真的需要延长的ActiveRecord,做这种方式:

ActiveRecord::Base.extend ModuleName 

当然还有很多其他的方式来编写插件依赖根据您的需求,以各种轨道gems为灵感。

+0

同样的事情;只是从你的答案复制粘贴的代码,我得到同样的错误 - 未定义的方法'键?'对于零:NilClass 我从Windows开发,所以现在我在我的Macbook Air上安装rails - 让我们看看问题是否存在。 – Ruslan

+0

对于最新的MacOs和Ubuntu 12.10绝对是一样的错误12.10 – Ruslan

+0

您能否用包含行号的异常回溯追加更多行来扩展您的问题?我相信它一定是非常微不足道的东西。谢谢。 – DaveTsunami

相关问题