Rails 4:after_find并包含冲突

时间:2016-01-14 12:15:51

标签: ruby-on-rails activerecord include

在我的Order模型中,我有一个has_many关联:

has_many :suborders, dependent: :destroy, inverse_of: :order

然而,在找到记录后我必须进行一些预处理,所以我也有一个after_find回调,如:

after_find :verify_validity
def verify_validity
   order.suborders.each do |suborder|
      ... doing something here with suborders ...
   end
end

然而,当我尝试用他们的子订单急切加载一批订单时,我得到了重复:

在控制器中:

@orders = Order.active.order(:updated_at => :desc).includes(:suborders)

在视图中:

Order is <%= order.inspect %>
<br />
Order suborders are <%= order.suborders.inspect %>

我得到了

Order is #<Order id: 1126, ...>
Order suborders are #<ActiveRecord::Associations::CollectionProxy [#<Suborder id: 119, order_id: 1126...>, #<Suborder id: 119, order_id: 1126...>]>

如何避免重复这种情况?

编辑:我还注意到系统正在进行两次相同的查询(第一次在after_find,然后再次由于includes)。如何after_find使用includes的结果? after_find中的一个效率非常低(n + 1个查询)。

1 个答案:

答案 0 :(得分:1)

这应该有效:

try { $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password); $stmt = $dbh->prepare("SELECT * FROM cities"); $stmt->execute(); $fields = array(); $csv = array(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { if (empty($fields)) { $fields = array_keys($row); array_push($csv, $fields); } array_push($csv, $row); } $fp = fopen('file.csv', 'w'); foreach ($csv as $row) { fputcsv($fp, $row); } fclose($fp); header("Content-type: application/csv"); header("Content-Disposition: attachment; filename=export.csv"); header("Pragma: no-cache"); header("Expires: 0"); readfile('file.csv'); $dbh = null; } catch (PDOException $e) { echo $e->getMessage(); }

Here's a post about it可能会给你一些其他想法。