2011-08-25 43 views
2

我有一个应用程序,其中用户列表可以根据某些条件进行过滤。一个这样的标准是用户在专业细节中提及的经验。我在应用程序的不同位置使用了不同类型的过滤器,并且具有与每个过滤器相对应的模型。其中一些具有通用功能。所以我提取了模块中的公共部分,它可以包含在任何模型中以获得所需的功能。我正试图在这里遵循单一责任的概念。浮动的默认值,基于mongoid中的相关模型

# 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

回答

1

我相信你不能那样做。你不能在你的field类方法中响应实例。 self对于fieldFilter::WorkOpportunity类,而不是您创建的实例。在你的情况下,你可以在after_initialize回调中为你的实例指定动态默认值,或者为max_exp创建你自己的getter,它将返回一些值,这取决于instnace状态。

+0

酷!将使用自定义getter。感谢帮助。 – rubish