Rails:包括不包括 [英] Rails :include doesn't include
问题描述
我的模特:
class Contact < ActiveRecord::Base
has_many :addresses
has_many :emails
has_many :websites
accepts_nested_attributes_for :addresses, :emails, :websites
attr_accessible :prefix, :first_name, :middle_name, :last_name, :suffix,
:nickname, :organization, :job_title, :department, :birthday,
:emails_attributes
end
class Email < ActiveRecord::Base
belongs_to :contact
validates_presence_of :account
validates_format_of :account, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
attr_accessible :contact_id, :account, :label
end
如果我运行以下查询,按预期返回电子邮件
:
If I run the following query, the emails
are returned as expected:
c = Contact.find(3)
Contact Load (3.2ms) SELECT `contacts`.* FROM `contacts` LIMIT 1
=> #<Contact id: 3, prefix: nil, first_name: "Micah", middle_name: nil, last_name: "Alcorn", suffix: nil, nickname: nil, organization: nil, job_title: nil, department: nil, birthday: nil, created_at: "2011-07-04 23:50:04", updated_at: "2011-07-04 23:50:04">
c.emails
Email Load (4.4ms) SELECT `emails`.* FROM `emails` WHERE `emails`.`contact_id` = 3
=> [#<Email id: 3, contact_id: 3, account: "not@real.address", label: "work", created_at: "2011-07-04 23:50:04", updated_at: "2011-07-04 23:50:04">]
然而,尝试 :include
关系不会:
c = Contact.find(3, :include => :emails)
Contact Load (0.5ms) SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`id` = 3 LIMIT 1
Email Load (0.8ms) SELECT `emails`.* FROM `emails` WHERE `emails`.`contact_id` IN (3)
=> #<Contact id: 3, prefix: nil, first_name: "Micah", middle_name: nil, last_name: "Alcorn", suffix: nil, nickname: nil, organization: nil, job_title: nil, department: nil, birthday: nil, created_at: "2011-07-04 23:50:04", updated_at: "2011-07-04 23:50:04">
如您所见,SQL正在执行,但不会返回电子邮件。我打算返回每个包含电子邮件的所有联系人,因此:join
将不会有任何好处。我缺少什么?
As you can see, the SQL is being executed, but the emails are not being returned. I intend to return all contacts with each containing email(s), so :joins
won't do any good. What am I missing?
推荐答案
电子邮件就在那里。你试过 c.emails
吗?您会发现电子邮件将在那里没有Rails执行额外的数据库查询。
The emails are there. Did you try c.emails
? You will find that the emails will be there without Rails doing an additional DB query.
:include
所做的事情叫做渴望加载,这基本上意味着Rails会尝试尽力而为的方法用他们的关系预先填充你的对象,这样当你真正要求关系时,不需要额外的数据库查询。
The thing that :include
does is called eager loading, which basically means Rails will try a best effort method of prepopulating your objects with their relations, so that when you actually ask for the relation no additional DB queries are needed.
参见渴望加载关联here:
http://api.rubyonrails.org /classes/ActiveRecord/Associations/ClassMethods.html
您可能还想查看此RailsCast:
http://railscasts.com/episodes/181-include-vs-joins
You might also want to check out this RailsCast:
http://railscasts.com/episodes/181-include-vs-joins
这篇关于Rails:包括不包括的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!