Это что-то вроде крушения поезда из-за того, как ActiveRecord пытается интерпретировать то, что вы говорите. Как правило, первый класс, производный от ActiveRecord :: Base, используется для определения имени базовой таблицы и подклассов, которые по умолчанию определены для использования в наследовании одной таблицы (STI). Вы работаете над этим, используя set_table_name
, но, как это часто бывает, хотя в Rails можно пойти против зернистости, все часто становится беспорядочным.
Вы должны быть в состоянии сделать это намного более аккуратно, используя миксин, как предложено Берлингтоном.
module ByNameExtension
def self.extended(base)
# This method is called when a class extends with this module
base.send(:scope, :by_name, lambda { |name|
name.blank? ? nil : where("#{self.table_name}.name LIKE ?", "%#{name}%")
})
end
def filter(params)
params[:name].present? ? self.by_name(params[:name]) : [ ]
end
end
class MyModel < ActiveRecord::Base
# Load in class-level methods from module ByNameExtension
extend ByNameExtension
end
Вы должны иметь возможность хранить свои расширения, содержащиеся в этом модуле. Если вы хотите убрать это еще дальше, напишите инициализатор, который определяет метод, подобный scoped_by_name
для ActiveRecord :: Base, который запускает это поведение:
class ActiveRecord::Base
def scoped_by_name
extend ByNameExtension
end
end
Затем вы можете пометить все классы, которые требуют этого:
class MyModel < ActiveRecord::Base
scoped_by_name
end