ActiveRecord如何使用哪里只有你查询的参数已经通过?

时间:2018-04-04 05:33:56

标签: ruby-on-rails ruby activerecord rails-activerecord

我正在运行如下的查询:

Item.where("created_at >=?", Time.parse(params[:created_at])).where(status_id: params[:status_id])

...用户可以决定不提供参数,在这种情况下,它应该完全从查询中排除。例如,如果用户决定不传递created_at而不提交,我想运行以下内容:

Item.where(status_id: params[:status_id])

即使您有try Time.try(:parse, params[:created_at])语句,我也在想,如果params[created_at]为空,那么查询将是.where(created_at >= ?", nil),这不是意图所有。与params[:status_id]相同的是,如果用户只是没有通过它,那么您的查询.where(status_id:nil)也不合适,因为这本身就是一个有效的查询!

我想你可以写这样的代码:

if params[:created_at].present?
  @items = Item.where("created_at >= ?", Time.parse(params[:created_at])
end
if params[:status_id].present?
  @items = @items.where(status_id: params[:status_id])
end

然而,对于多个db调用来说效率较低,而且我正在努力提高效率。只是想知道是否可能。

2 个答案:

答案 0 :(得分:0)

def index
  @products = Product.where(nil) # creates an anonymous scope
  @products = @products.status(params[:status]) if params[:status].present?
  @products = @products.location(params[:location]) if params[:location].present?
  @products = @products.starts_with(params[:starts_with]) if params[:starts_with].present?
end

你可以这样做。 Rails是聪明的,以便确定何时需要构建查询;)

您可能有兴趣查看this blog这对我非常有用,也可以为您服务。

答案 1 :(得分:0)

如果您阅读#where文档,则可以看到将nil传递给where子句的选项。

  

空白条件:   如果条件是任何空白对象,则#where是无操作并返回当前关系。

这使我们可以选择在有效时传递条件,或者只返回nil会产生先前的关系。

@items = Item.where(status_condition).where(created_at_condition)

private

def status_condition
  ['status = ?', params[:status]] unless params[:status].blank?
end

def created_at_condition
  ['created_at >= ?', Time.parse(params[:created_at])] unless params[:created_at].blank?
end

这是实现预期结果的另一种选择。希望这有帮助!