我有一个应用,可以根据某些条件过滤用户列表。一个这样的标准是在专业细节中提到的用户的体验。我在应用程序的不同位置有不同类型的过滤器,并且具有与每个过滤器对应的模型。其中一些具有共同的功能。因此,我在模块中提取了公共部分,该模块可以包含在任何模型中以获得所需的功能。我想在这里遵循单一责任的概念。
# model
class Filter::WorkOpportunity
include Mongoid::Document
include Filter::NotificationSubFilter
include Filter::User::Qualification
include Filter::User::Experience
belongs_to :college
def matched_user_ids
# ...
end
end
# one of the included module I am having problems with
# others work fine
module Filter::User::Experience
extend ActiveSupport::Concern
DEFAULT_MAX_EXP = 10.0
included do
include InstanceMethods
field :min_exp, :type => Float, :default => 0.0
field :max_exp, :type => Float, :default => lambda { default_max_exp }
end
module InstanceMethods
# Appends users criteria passed, to filter on qualifications
def filter_experience users=nil
# ...
end
def default_max_exp
@default_max_exp ||= begin
established_at = self.college.try(:established_at)
if established_at.blank?
DEFAULT_MAX_EXP
else
[(Time.now.year - established_at.year + 1), DEFAULT_MAX_EXP].max.to_f
end
end
end
end
end
我尝试初始化过滤器时出错。
NameError: undefined local variable or method `default_max_exp' for Filter::WorkOpportunity:Class
其他包含的模块具有类似的结构。即使我将default_max_exp
移动到included
块,它仍然无效。
当我在这里发布问题时,我意识到这是因为default_max_exp
应该是一个类方法,它是一个实例方法。但我希望默认值基于实例,因为不同的过滤器可以属于不同的大学,默认的最大经验应该基于大学。
我如何拥有基于实例的默认值?
RoR:3.0.4,Mongoid:2.0.2
答案 0 :(得分:1)
我相信你做不到。您无法在field
类方法中回复实例。 self
的{{1}}是field
类,而不是您创建的实例。在您的情况下,您可以在Filter::WorkOpportunity
回调中为实例指定动态默认值,或为after_initialize
创建自己的getter,这将返回一些取决于instnace状态的值。