Rails: вызов метода внутри модели - PullRequest
6 голосов
/ 17 июля 2009

Не могу понять это. В модели 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 ]

4 голосов
/ 17 июля 2009

Частично проблема в том, что вы определяете метод класса с именем 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])

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

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

3 голосов
/ 09 августа 2011

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

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

Используйте self.filter_my_rows для определения вашей функции (обратите внимание на self), и все пойдет правильно.

2 голосов
/ 17 июля 2009

используйте named_scope вместо

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

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

@date = Model.current

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

0 голосов
/ 17 июля 2009

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

Этот метод '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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...