0

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

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

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所以我认为有一种更好的方法可以从那里获取我需要的一条记录——而不是再次回到数据库。

4

2 回答 2

0

您可以使用find内置于所有 Enumerables...

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])

如果你真的希望它是一个数组,只需将结果包装在[].

于 2013-03-28T17:34:28.810 回答
0

这个怎么样

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参数时执行(并非总是如此)。我相信它更有效,而不是从数据库中选择所有然后过滤

于 2013-03-28T22:15:25.753 回答