@people = People.scoped
@people = @people.where(...) if ...
@people = @people.where(...) if ...
@people = @people.where(...) if ...
@people = @people.where(...) if ...
是否有任何红宝石现有解决方案可以制作类似
的内容@people = People.scoped
@people.???? do
where(...) if ...
where(...) if ...
where(...) if ...
end
PS:谢谢你的回答。但是您提供的解决方案看起来像
def self.conditional_scope
where(...) if ...
where(...) if ...
where(...) if ...
end
我想即使所有“如果”都是真的,我也只会到最后。
我是对的吗?
答案 0 :(得分:2)
我认为你应该熟悉named_scopes: http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html
它们是可组合的,因此您可以编写如下内容:
People.tall.having_children.older_than(30)
其中“tall”,“having_children”和“older_than”被命名为范围。
答案 1 :(得分:1)
是。您只需将其移至模型:
# Controller
@people = People.find_my_guy
# Model
def self.find_my_guy
where(...) if ...
where(...) if ...
where(...) if ...
end
显然,如果在你的语句中使用了一些环境变量,你需要将它们传递给你的模型:
# Controller
@people = People.find_my_guy(params)
# Model
def self.find_my_guy(params)
where(:id => params[:id]) if params[:id]
where('title LIKE (?)', "%#{params[:search]}%") if parmas[:search]
where(...) if ...
end
就你上一次where
而言你是对的,我只能建议在这里进行方法链接(像@socjopata那样({/ p>
# Model
def self.with_name(name)
where(:name => name) if name.present?
end
def self.with_id_gt(id)
where('id >= ?', id) if id.to_i > 3
end
# Controller
Post.with_name(parms[:name]).with_id_gt(params[:id])
答案 2 :(得分:1)
def self.conditional_scope
where(...) if ...
where(...) if ...
where(...) if ...
end
然后:
Model.conditional_scope
答案 3 :(得分:1)
如果我理解你的要求,你只想在条件存在的情况下应用每个范围......你可以使用带有lambda的命名范围,然后将它们链接起来:
scope :one, lambda {|condition| condition ? where(...) : {}}
scope :two, lambda {|condition| condition ? where(...) : {}}
...
@people = Person.one(true).two(false)
答案 4 :(得分:0)
也许您正在寻找避免在每个where
子句后明确分配新范围的方法?您可能对此railscast感兴趣:http://railscasts.com/episodes/212-refactoring-dynamic-delegator。 Ryan Bates使用委托人来实现这样的代码:
def self.search(params)
products = scope_builder
products.where("name like ?", "%" + params[:name] + "%") if params[:name]
products.where("price >= ?", params[:price_gt]) if params[:price_gt]
products.where("price <= ?", params[:price_lt]) if params[:price_lt]
products
end