Rails: включить не включить - PullRequest
0 голосов
/ 05 июля 2011

Мои модели:

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: "not@real.address", label: "work", created_at: "2011-07-04 23:50:04", updated_at: "2011-07-04 23:50:04">]

Однако при попытке :include связь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">

Как видите, SQL выполняется, но электронные письма не возвращаются.Я намерен вернуть все контакты, содержащие каждое электронное письмо, поэтому :joins не поможет.Чего мне не хватает?

1 Ответ

2 голосов
/ 05 июля 2011

Письма есть.Вы пробовали c.emails?Вы обнаружите, что электронные письма будут там без Rails, делающего дополнительный запрос БД.

То, что делает :include, называется энергичной загрузкой, что в основном означает, что Rails постарается сделать все возможное, чтобы предварительно заполнить ваши объекты их отношениями, так что когда вы фактически запрашиваете отношение, никаких дополнительных запросов к БД не происходит.Нужен.

См. раздел " Стремительная загрузка ассоциаций " здесь: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Вы также можете проверить этот RailsCast:
http://railscasts.com/episodes/181-include-vs-joins

...