【问题标题】:Find in ActiveRecord object在 ActiveRecord 对象中查找
【发布时间】:2013-03-28 17:32:34
【问题描述】:

我有一个页面可以显示所有客户的详细信息,或者如果在参数中指定,则仅显示一个客户的详细信息。

我的控制器看起来像这样。

def display_customers
  @all_customers = Customer.all
  if params[:customer_id]
    @customers = Customer.find(:all, conditions: ["id = ?", params[:customer_id]])
  else
    @customers = @all_customers
  end
end

我使用@all_customers 填充客户下拉列表。
我使用@customers 对每个客户执行each 循环。
然后,如果指定了 customer_id 参数,@customers 将只是单个客户。

这很好用,但@customers = Customer.find(...) 是一个额外的数据库查询。
我已经拥有@all_customers 中的所有客户,所以我认为会有更好的方法从那里获取我需要的一条记录 - 而不是再次回到数据库。

【问题讨论】:

  • 你真的应该,真的开始每级缩进使用两个空格。在 Ruby 社区内,您不能自己制作缩进样式。

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


【解决方案1】:

您可以使用所有 Enumerable 中内置的 find...

if params[:customer_id]
  @customer = @all_customers.find { |c| c.id == params[:customer_id] }
else
  #...

...但可能不应该。

根据记录的数量,这可能不会更快,因为您的数据库查询将使用索引,上面的代码对所有返回的记录使用线性搜索。很有可能第二个数据库查询是要走的路。

您还应该重写您的查询。 Rails 足够聪明,您在通过 ID 查找记录时不必传递条件;你只需找到它。它们是相同的:

# BAD:
@customers = Customer.find(:all, conditions: ["id = ?", params[:customer_id]])

# BETTER:
@customers = Customer.find_by_id(params[:customer_id])

# BEST:
@customer = Customer.find(params[:customer_id])

如果您真的希望它是一个数组,只需将结果包装在 [] 中即可。

【讨论】:

  • 谢谢。我想我的印象是减少查询是要走的路。很有帮助。
【解决方案2】:

这个怎么样

def display_customers
  @all_customers = []
  if params[:customer_id].empty?
    @all_customers = Customer.all
  else 
    @all_customers << Customer.find(params[customer_id])
  end
  @all_customers
end

这边

您的“select * from customers”查询只会在没有customer_id 参数时执行(并非总是如此)。我相信它比从数据库中选择所有然后过滤更有效

【讨论】:

  • 无论如何我都需要得到它们,因为我正在为所有客户创建一个
猜你喜欢
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多