我的插件需要一些帮助。我想用一个初始化可以在控制器中调用的另一个方法的方法来扩展ActiveRecord::Base
。
看起来像这样:
class Article < ActiveRecord::Base
robot_catch :title, :text
...
end
我尝试使用ActiveRecord::Base
方法扩展robot_catch
类似乎如下。该函数将初始化变量中的指定属性(在本例中为:title
和:text
),并使用class_eval
使robot?
函数可供用户调用控制器:
module Plugin
module Base
extend ActiveSupport::Concern
module ClassMethods
def robot_catch(*attr)
@@robot_params = attr
self.class_eval do
def robot?(params_hash)
# Input is the params hash, and this function
# will check if the some hashed attributes in this hash
# correspond to the attribute values as expected,
# and return true or false.
end
end
end
end
end
end
ActiveRecord::Base.send :include, Plugin::Base
因此,在控制器中,可以这样做:
class ArticlesController < ApplicationController
...
def create
@article = Article.new(params[:article])
if @article.robot? params
# Do not save this in database, but render
# the page as if it would have succeeded
...
end
end
end
我的问题是我是否正确robot_catch
是类方法。如上所示,此函数将在模型内部调用。我想知道我是否正在以正确的方式延长ActiveRecord::Base
。 robot?
函数毫无疑问是一种实例方法。
我正在使用Rails 3.2.22,我在另一个项目中将此插件安装为gem,我想使用此功能。
现在,只有在模型中特定require
宝石时,它才有效。但是,我希望将功能作为ActiveRecord::Base
的一部分包含在内而不需要它,否则我必须在我想要使用它的每个模型中require
,而不是特别 DRY 。不应该在Rails启动时将gem自动加载到项目中吗?
编辑:也许回调(http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html)可以解决此问题,但我不知道如何使用它。这看起来有点模糊。
答案 0 :(得分:0)
首先,我建议您确保none of the many many built in Rails validators meet your needs。
如果是这样的话,你真正想要的是一个自定义验证器。
构建自定义验证器并不像看起来那么简单,您构建的基本类将具有以下结构:
class SpecialValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
# Fill this with your validation logic
# Add to record.errors if validation fails
end
end
然后在你的模型中:
class Article < ActiveRecord::Base
validates :title, :text, special: true
end
我会强烈建议确保你想要的东西还没有建成,很有可能。然后使用resources like this或ruby guides resources继续关闭自定义验证程序路径。
答案 1 :(得分:0)
我自己找到了解决方案。 Bundler不会从我的项目使用的gemspec中自动加载依赖项,因此我必须在我的应用程序的lib /目录中的engine.rb文件中要求所有第三方gem,以便加载gem。现在一切正常。
第二:robot_catch
方法是一种类方法。