Rails : 包括 不包括

发布于 2024-11-18 14:07:39 字数 2102 浏览 9 评论 0原文

我的模型:

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

如果我运行以下查询,emails 将按预期返回:

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: "[email protected]", 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 是正在执行,但电子邮件没有被返回。我打算返回所有包含电子邮件的联系人,因此 :joins 不会有任何好处。我缺少什么?

My models:

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: "[email protected]", label: "work", created_at: "2011-07-04 23:50:04", updated_at: "2011-07-04 23:50:04">]

However, attempting to :include the relationship does not:

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">

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绅士风度i 2024-11-25 14:07:40

电子邮件就在那里。您尝试过c.emails吗?您会发现电子邮件将在那里,而无需 Rails 执行额外的数据库查询。

:include 所做的事情称为急切加载,这基本上意味着 Rails 将尝试尽最大努力用对象的关系预先填充对象,这样当您实际请求关系时,就不会再进行额外的数据库查询。需要。

请参阅此处的“关联的预加载”部分:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

您可能还想查看这个 RailsCast:
http://railscasts.com/episodes/181-include-vs-joins

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.

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.

See the section "Eager loading of associations" here:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

You might also want to check out this RailsCast:
http://railscasts.com/episodes/181-include-vs-joins

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文