加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 高效的连接查询 – 可以使用ActiveRecord完成

发布时间:2020-12-17 03:01:54 所属栏目:百科 来源:网络整理
导读:我有4个型号,A,B,C和D. class A ActiveRecord::Base has_many :B has_many :C,:through = :Bend class B ActiveRecord::Base belongs_to :A has_many :C has_many :D,:through = :Cend class C ActiveRecord::Base belongs_to :Bend class D ActiveRecord::B
我有4个型号,A,B,C和D.

class A < ActiveRecord::Base
  has_many :B
  has_many :C,:through => :B
end  

class B < ActiveRecord::Base
  belongs_to :A  
  has_many   :C
  has_many   :D,:through => :C
end  

class C < ActiveRecord::Base    
  belongs_to :B
end    

class D < ActiveRecord::Base    
  belongs_to :C
end

我有一个非常天真的实现,非常明显……

<% A.B.each do |b| %>
  <%= b.number %>
  <% b.C.each do |c| %>
    <%= c.name %>
  <% end %>
<% end %>

获得All C for A的最佳方法是什么?
获得All D for A的最佳方式是什么?

我希望使用带有“created_at”值的order_by子句而不是迭代B来获取所有’C’.

可能是我错过了一些ActiveRecord魔法?

我感谢任何帮助.

解决方法

首先,您需要进行一些更改.

> C类需要与D的关联

class C < ActiveRecord::Base
  belongs_to :B
  has_one :D
end

>如果你想访问A的D,你也需要指定它.

class A < ActiveRecord::Base
  has_many :B
  has_many :C,:through => :B
  has_many :D,:through => :C
end

现在,要访问所有A的C:

-> a = A.where(:id => 1).includes(:C).first
  A Load (0.2ms)  SELECT "as".* FROM "as" WHERE "as"."id" = 1 LIMIT 1
  B Load (0.1ms)  SELECT "bs".* FROM "bs" WHERE "bs"."a_id" IN (1)
  C Load (0.1ms)  SELECT "cs".* FROM "cs" WHERE "cs"."b_id" IN (1,2)
 => #<A id: 1,created_at: "2012-01-10 04:28:42",updated_at: "2012-01-10 04:28:42"> 
-> a.C
 => [#<C id: 1,b_id: 1,created_at: "2012-01-10 04:30:10",updated_at: "2012-01-10 04:30:10">,#<C id: 2,created_at: "2012-01-10 04:30:11",updated_at: "2012-01-10 04:30:11">,#<C id: 3,b_id: 2,created_at: "2012-01-10 04:30:21",updated_at: "2012-01-10 04:30:21">,#<C id: 4,updated_at: "2012-01-10 04:30:21">]

请注意当您调用a.C时,如何不执行另一个查询.这是因为ActiveRecord知道您将要通过include调用访问找到的A的C,并生成最少数量的查询.同样适用于D:

-> a = A.where(:id => 1).includes(:D).first
  A Load (0.1ms)  SELECT "as".* FROM "as" WHERE "as"."id" = 1 LIMIT 1
  B Load (0.1ms)  SELECT "bs".* FROM "bs" WHERE "bs"."a_id" IN (1)
  C Load (0.1ms)  SELECT "cs".* FROM "cs" WHERE "cs"."b_id" IN (1,2)
  D Load (0.1ms)  SELECT "ds".* FROM "ds" WHERE "ds"."c_id" IN (1,2,3,4)

假设你想要所有A的D’但是想要C的订购:

A.where(:id => 1).includes(:C).order('cs.created_at DESC').includes(:D)

请注意,您还可以将此设置为关联的默认值:

The :order option dictates the order in which associated objects will be received (in the syntax used by an SQL ORDER BY clause).

06005

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读