0

首先,我还是ROR的新手,我试图想出更有效的方法来为我的数据表做数据库查询。Rails数据库查询ROR

我的模特协会

class Store < ActiveRecord::Base 
    has_many :surveys 
    has_many :customers 
end 
... 
class Survey < ActiveRecord::Base 
    belongs_to :store 
end 
... 
class Customer < ActiveRecord::Base 
    belongs_to :store 
end 

在我的DataTable

  <tbody> 
      <% @store.surveys.each do |survey| %> 
      <tr class="th-container table-fixer"> 
       <td><%= find_customer_id(survey.email).nil? ? survey.first_name : link_to(survey.first_name, store_customer_path(@store, find_customer_id(survey.email))) %></td> 
       <td><%= get_ltv(survey) %></td>   
      </tr> 
      <% end %> 
      </tbody> 

find_customer_id和get_ltv方法如下

def find_customer_id(customer_email) 
    BwCustomer.find_by(email: customer_email) 
end 

与代码的问题是,目前我有超过1000我循环的活动记录对象,当find_customer_id方法被击中时,它会找到cus使用给定的电子邮件地址,并且查询需要15秒来处理。

在我的情况下,最好的方法是什么?

的解决方案,我虽然了解: 1.参加表格,让我没有打电话给另一台 2.延迟加载,仅在需要时

一些建议,将大大加载的对象赞赏

谢谢

回答

1

通过电子邮件ID您的查询不应该拿这么多的时间。

  1. 添加指数电子邮件客户表(请参阅此通过活动记录迁移添加索引 - http://apidock.com/rails/v4.2.1/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

  2. 您的代码显示调用find_customer_id两次。做一次这样只有1个数据库查询被触发

  3. 你不需要写一个包装方法 - Customer.find_by_email(customer_email)也适用

为了进一步优化,你可以收集你需要检查存在的所有客户ID在一个循环的数据库,并触发一个单独的数据库查询: Customer.where(email: [list of customer emails])

0

的主要问题是,你缺失的客户和调查之间的关联。你可以通过加入电子邮件

class Survey < ActiveRecord::Base 
    belongs_to :customer, primary_key: :email, foreign_key: :email 
end 

但这是一个有点粗略的方法。您填写调查时,您的申请是否知道客户的ID?或者,这些调查是否可以由任何人填写,并且如果有人声称与客户拥有相同的电子邮件,您就可以建立链接?

在任何情况下,您都需要将电子邮件列编入索引,并且如果您在两者之间建立关联,则可以在控制器代码中编写以下内容。

@store = Store.includes(surveys: :customer).find(params[store_id]) 

这将使数据库查询其急于加载所有的调查,你是要显示,这样的循环中,你可以使用survey.customer无需为每一行调用一个新的查询客户。