Rails: метод вызова в модели

Не могу понять это. В модели rails я хочу вызвать метод в той же модели для управления данными, возвращаемыми методом find. Этот метод фильтра будет вызываться из многих пользовательских методов поиска в этой модели, поэтому я хочу, чтобы он был отдельным. (и я не могу отфильтровать из SQL это слишком сложно)

вот пример:

#controller
@data = Model.find_current

#model
class Model
  def self.find_current
    @rows = find(:all)
    filter_my_rows
    return @rows
  end

  def filter_my_rows
    #do stuff here on @rows
    for row in @rows
      #basically I remove rows that do not meet certain conditions
    end
  end
end

результат этого: неопределенный метод 'filter_my_rows'

Спасибо за любую помощь!

4 ответов


часть проблемы заключается в том, что вы определяете метод класса find_current и метод экземпляра filter_my_rows. Как правило, вы определяете их в одной и той же области для совместной работы.

другое дело, что вы можете сделать много фильтрации вам нужно с помощью простого Array#reject вызова. Например:

@models = all.reject do |m|
   # This block is used to remove entries that do not qualify
   # by having this evaluate to true.
   !m.current
end

Вы можете смоделировать такое подключение необходимых функций, но что можно сделать дико сложно управлять, если ты не осторожный.

# Define reusable blocks that are organized into a Hash
CONDITION_FILTERS = {
  :current => lambda { |m| m.current }
}

# Array#select is the inverse of Array#reject
@models = all.select(CONDITION_FILTERS[:current])

хотя вы заявили в своем вопросе, что это было необходимо только из-за опасений о невозможности определить релевантность конкретной записи до того, как все записи будут загружены из базы данных, это, как правило, плохая форма, так как вы, вероятно, будете отклонять большое количество данных, которые вы прошли через проблемы извлечения и создания экземпляров в качестве моделей только для того, чтобы немедленно отбросить их.

Если возможно, вы должны по крайней мере кэш извлеченные строки в течение всего запроса, поэтому вам не нужно продолжать получать их снова и снова.


функция класса и функция экземпляра-ваша проблема.

вы не можете вызвать функцию экземпляра в своей функции класса таким образом.

использовать self.filter_my_rows чтобы определить вашу функцию (обратите внимание на self) и все будет хорошо.


вместо того, чтобы использовать named_scope

named_scope :current, :conditions => {:active => true} # this is normal find criteria

тогда в ваш контроллер

@date = Model.current

вы также можете сделать named_scopes лямбда-функции


что не так с вашими решениями? Что именно вы ищете? Если я понял вашу точку зрения, основная проблема реализации заключается в том, что

этот метод 'filter' будет вызван из многих пользовательских методов поиска внутри эта модель, поэтому я хочу, чтобы она была отделять.

... что вы не можете использовать named_scopes или with_scope, первое решение, которое приходит мне на ум, - создать пользовательскую оболочку для действия в качестве фильтра.

class Model
  def self.find_current
    filtered do
      all
    end
  end

  def self.other_method
    filtered do
      all :conditions => { :foo => "bar" }
    end
  end

  def self.filtered(&block)
    records = yield
    # do something with records
    records
  end

end