在ActiveRecord对象中查找

时间:2013-03-28 17:32:34

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

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

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

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中的所有客户,所以我可以更好地从那里获取我需要的一条记录 - 而不是再次回到数据库。

2 个答案:

答案 0 :(得分:0)

您可以使用内置于所有Enumerables中的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])

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

答案 1 :(得分: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”查询(并非总是如此)。我认为它更有效,而不是从数据库中选择所有,然后过滤