我有一个用例,我希望能够在控制器的索引操作中过滤集合
params[:ids]
我使用范围或类方法将过滤委托给模型:
class Zombie < ActiveRecord::Base
has_many :weapons
def self.filter_by_weapons(weapons)
where(weapons: weapons)
end
end
在控制器中
def index
@zombies = Zombie.filter_by_weapons(current_user.weapons)
end
效果很好。但是,如果我希望我的应用程序能够根据ID列表过滤zombies
,我会这样做:
def index
@zombies = Zombie.filter_by_weapons(current_user.weapons)
if params[:weapons_ids]
@zombies = @zombies.filter_by_weapons(Weapon.where(id: params[:weapon_ids]))
end
end
然而,这打破了在控制器操作中只应调用一个模型的规则。
我尝试按ID而不是模型实例进行搜索,但问题是相反的,我必须映射current_user.weapons
那么,最好的方法是什么?
答案 0 :(得分:0)
您可以将方法重构为以下内容:
def self.filter_by_weapons(weapons)
weapon_ids = weapons.first.kind_of?(Weapon) ? weapons.map(&:id) : weapons
where(weapons: { id: weapon_ids.presence || -1 })
end
并像这样使用它:
def index
@zombies = Zombie.filter_by_weapons(current_user.weapons)
@zombies = @zombies.filter_by_weapons(params[:weapon_ids]) if params[:weapons_ids].present?
end