开发者

Rails :include doesn't include

开发者 https://www.devze.com 2023-03-17 01:45 出处:网络
My models: class Contact < ActiveRecord::Base has_many :addresses has_man开发者_开发问答y :emails

My models:

class Contact < ActiveRecord::Base
  has_many :addresses
  has_man开发者_开发问答y :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">]

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?


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

0

精彩评论

暂无评论...
验证码 换一张
取 消