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