Значение по умолчанию для поплавка на основе связанной модели в монгоиде - PullRequest
2 голосов
/ 25 августа 2011

У меня есть приложение, в котором список пользователей может быть отфильтрован по некоторым критериям. Одним из таких критериев является опыт пользователя, упомянутый в профессиональных деталях. У меня есть разные виды фильтров в разных местах приложения, и у меня есть модель, соответствующая каждому фильтру. некоторые из них имеют общую функциональность. Поэтому я извлек общую часть в модуле, которую можно включить в любую модель, чтобы получить необходимую функциональность. Я пытаюсь следовать концепции единой ответственности здесь.

# 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 Ответ

1 голос
/ 25 августа 2011

Я верю, что ты не можешь этого сделать. Вы не можете ответить на экземпляр в вашем field методе класса. self для field - это класс Filter::WorkOpportunity, а не экземпляр, который вы создали. В вашем случае вы можете указать динамические значения по умолчанию для ваших экземпляров в after_initialize обратном вызове или создать свой собственный метод получения для max_exp, который будет возвращать некоторое значение, которое будет зависеть от состояния экземпляра.

...