I have an app, where users list can be filtered on some criteria. One such criteria is experience of the user an mentioned in professional details. I have different kind of filters at different places in app and have a model corresponding to each filter. some of them have common functionality. So I extracted the common portion in a module, which can be included in any model to get the required functionality. I am trying to follow the concept of Single Responsibility here.
# 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
I get an error when I try to initialize the filter.
NameError: undefined local variable or method `default_max_exp' for Filter::WorkOpportunity:Class
Other included modules have similar structure. Even if I move the default_max_exp
to the inc开发者_JS百科luded
block, it still doesn't work.
While I was posting the question here I realized that it is because, the default_max_exp
should be a class method, and it is an instance method. But I want the default value to instance based, as the different filters can belong to different colleges and default maximum experience should be based on college.
How can I have an instance based default?
RoR: 3.0.4, Mongoid: 2.0.2
I believe you can't do that. You can't respond to instance in your field
class method. self
for field
is a Filter::WorkOpportunity
class, not an instance you have created. In your case you can specify dynamic defaults for your instances in after_initialize
callback or create your own getter for max_exp
which will return some value which will depends on instnace state.
精彩评论