PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/activerecord/lib/active_record/associations.rb

https://github.com/ghar/rails
Ruby | 1012 lines | 135 code | 29 blank | 848 comment | 4 complexity | 9c652617bb4669bc6f6257f73a32ce76 MD5 | raw file
  1. require 'active_support/core_ext/array/wrap'
  2. require 'active_support/core_ext/enumerable'
  3. require 'active_support/core_ext/module/delegation'
  4. require 'active_support/core_ext/object/blank'
  5. require 'active_support/core_ext/string/conversions'
  6. require 'active_support/core_ext/module/remove_method'
  7. require 'active_support/core_ext/class/attribute'
  8. module ActiveRecord
  9. class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
  10. def initialize(reflection, associated_class = nil)
  11. super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
  12. end
  13. end
  14. class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
  15. def initialize(owner_class_name, reflection)
  16. super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}")
  17. end
  18. end
  19. class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
  20. def initialize(owner_class_name, reflection, source_reflection)
  21. super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}'.")
  22. end
  23. end
  24. class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
  25. def initialize(owner_class_name, reflection)
  26. super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
  27. end
  28. end
  29. class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
  30. def initialize(owner_class_name, reflection, source_reflection)
  31. super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
  32. end
  33. end
  34. class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
  35. def initialize(owner_class_name, reflection, through_reflection)
  36. super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
  37. end
  38. end
  39. class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
  40. def initialize(reflection)
  41. through_reflection = reflection.through_reflection
  42. source_reflection_names = reflection.source_reflection_names
  43. source_associations = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect }
  44. super("Could not find the source association(s) #{source_reflection_names.collect{ |a| a.inspect }.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
  45. end
  46. end
  47. class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
  48. def initialize(owner, reflection)
  49. super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
  50. end
  51. end
  52. class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
  53. def initialize(owner, reflection)
  54. super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
  55. end
  56. end
  57. class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
  58. def initialize(owner, reflection)
  59. super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
  60. end
  61. end
  62. class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc
  63. def initialize(owner, reflection)
  64. super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
  65. end
  66. end
  67. class HasAndBelongsToManyAssociationForeignKeyNeeded < ActiveRecordError #:nodoc:
  68. def initialize(reflection)
  69. super("Cannot create self referential has_and_belongs_to_many association on '#{reflection.class_name rescue nil}##{reflection.name rescue nil}'. :association_foreign_key cannot be the same as the :foreign_key.")
  70. end
  71. end
  72. class EagerLoadPolymorphicError < ActiveRecordError #:nodoc:
  73. def initialize(reflection)
  74. super("Can not eagerly load the polymorphic association #{reflection.name.inspect}")
  75. end
  76. end
  77. class ReadOnlyAssociation < ActiveRecordError #:nodoc:
  78. def initialize(reflection)
  79. super("Can not add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
  80. end
  81. end
  82. # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
  83. # (has_many, has_one) when there is at least 1 child associated instance.
  84. # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
  85. class DeleteRestrictionError < ActiveRecordError #:nodoc:
  86. def initialize(name)
  87. super("Cannot delete record because of dependent #{name}")
  88. end
  89. end
  90. # See ActiveRecord::Associations::ClassMethods for documentation.
  91. module Associations # :nodoc:
  92. extend ActiveSupport::Concern
  93. # These classes will be loaded when associations are created.
  94. # So there is no need to eager load them.
  95. autoload :Association, 'active_record/associations/association'
  96. autoload :SingularAssociation, 'active_record/associations/singular_association'
  97. autoload :CollectionAssociation, 'active_record/associations/collection_association'
  98. autoload :CollectionProxy, 'active_record/associations/collection_proxy'
  99. autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
  100. autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
  101. autoload :HasAndBelongsToManyAssociation, 'active_record/associations/has_and_belongs_to_many_association'
  102. autoload :HasManyAssociation, 'active_record/associations/has_many_association'
  103. autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association'
  104. autoload :HasOneAssociation, 'active_record/associations/has_one_association'
  105. autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
  106. autoload :ThroughAssociation, 'active_record/associations/through_association'
  107. module Builder #:nodoc:
  108. autoload :Association, 'active_record/associations/builder/association'
  109. autoload :SingularAssociation, 'active_record/associations/builder/singular_association'
  110. autoload :CollectionAssociation, 'active_record/associations/builder/collection_association'
  111. autoload :BelongsTo, 'active_record/associations/builder/belongs_to'
  112. autoload :HasOne, 'active_record/associations/builder/has_one'
  113. autoload :HasMany, 'active_record/associations/builder/has_many'
  114. autoload :HasAndBelongsToMany, 'active_record/associations/builder/has_and_belongs_to_many'
  115. end
  116. autoload :Preloader, 'active_record/associations/preloader'
  117. autoload :JoinDependency, 'active_record/associations/join_dependency'
  118. autoload :AssociationScope, 'active_record/associations/association_scope'
  119. autoload :AliasTracker, 'active_record/associations/alias_tracker'
  120. autoload :JoinHelper, 'active_record/associations/join_helper'
  121. # Clears out the association cache.
  122. def clear_association_cache #:nodoc:
  123. @association_cache.clear if persisted?
  124. end
  125. # :nodoc:
  126. attr_reader :association_cache
  127. # Returns the association instance for the given name, instantiating it if it doesn't already exist
  128. def association(name) #:nodoc:
  129. association = association_instance_get(name)
  130. if association.nil?
  131. reflection = self.class.reflect_on_association(name)
  132. association = reflection.association_class.new(self, reflection)
  133. association_instance_set(name, association)
  134. end
  135. association
  136. end
  137. private
  138. # Returns the specified association instance if it responds to :loaded?, nil otherwise.
  139. def association_instance_get(name)
  140. @association_cache[name.to_sym]
  141. end
  142. # Set the specified association instance.
  143. def association_instance_set(name, association)
  144. @association_cache[name] = association
  145. end
  146. # Associations are a set of macro-like class methods for tying objects together through
  147. # foreign keys. They express relationships like "Project has one Project Manager"
  148. # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
  149. # class which are specialized according to the collection or association symbol and the
  150. # options hash. It works much the same way as Ruby's own <tt>attr*</tt>
  151. # methods.
  152. #
  153. # class Project < ActiveRecord::Base
  154. # belongs_to :portfolio
  155. # has_one :project_manager
  156. # has_many :milestones
  157. # has_and_belongs_to_many :categories
  158. # end
  159. #
  160. # The project class now has the following methods (and more) to ease the traversal and
  161. # manipulation of its relationships:
  162. # * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
  163. # * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
  164. # * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
  165. # <tt>Project#milestones.delete(milestone), Project#milestones.find(milestone_id), Project#milestones.all(options),</tt>
  166. # <tt>Project#milestones.build, Project#milestones.create</tt>
  167. # * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt>
  168. # <tt>Project#categories.delete(category1)</tt>
  169. #
  170. # === A word of warning
  171. #
  172. # Don't create associations that have the same name as instance methods of
  173. # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
  174. # its model, it will override the inherited method and break things.
  175. # For instance, +attributes+ and +connection+ would be bad choices for association names.
  176. #
  177. # == Auto-generated methods
  178. #
  179. # === Singular associations (one-to-one)
  180. # | | belongs_to |
  181. # generated methods | belongs_to | :polymorphic | has_one
  182. # ----------------------------------+------------+--------------+---------
  183. # other | X | X | X
  184. # other=(other) | X | X | X
  185. # build_other(attributes={}) | X | | X
  186. # create_other(attributes={}) | X | | X
  187. # create_other!(attributes={}) | X | | X
  188. #
  189. # ===Collection associations (one-to-many / many-to-many)
  190. # | | | has_many
  191. # generated methods | habtm | has_many | :through
  192. # ----------------------------------+-------+----------+----------
  193. # others | X | X | X
  194. # others=(other,other,...) | X | X | X
  195. # other_ids | X | X | X
  196. # other_ids=(id,id,...) | X | X | X
  197. # others<< | X | X | X
  198. # others.push | X | X | X
  199. # others.concat | X | X | X
  200. # others.build(attributes={}) | X | X | X
  201. # others.create(attributes={}) | X | X | X
  202. # others.create!(attributes={}) | X | X | X
  203. # others.size | X | X | X
  204. # others.length | X | X | X
  205. # others.count | X | X | X
  206. # others.sum(args*,&block) | X | X | X
  207. # others.empty? | X | X | X
  208. # others.clear | X | X | X
  209. # others.delete(other,other,...) | X | X | X
  210. # others.delete_all | X | X | X
  211. # others.destroy_all | X | X | X
  212. # others.find(*args) | X | X | X
  213. # others.exists? | X | X | X
  214. # others.uniq | X | X | X
  215. # others.reset | X | X | X
  216. #
  217. # == Cardinality and associations
  218. #
  219. # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
  220. # relationships between models. Each model uses an association to describe its role in
  221. # the relation. The +belongs_to+ association is always used in the model that has
  222. # the foreign key.
  223. #
  224. # === One-to-one
  225. #
  226. # Use +has_one+ in the base, and +belongs_to+ in the associated model.
  227. #
  228. # class Employee < ActiveRecord::Base
  229. # has_one :office
  230. # end
  231. # class Office < ActiveRecord::Base
  232. # belongs_to :employee # foreign key - employee_id
  233. # end
  234. #
  235. # === One-to-many
  236. #
  237. # Use +has_many+ in the base, and +belongs_to+ in the associated model.
  238. #
  239. # class Manager < ActiveRecord::Base
  240. # has_many :employees
  241. # end
  242. # class Employee < ActiveRecord::Base
  243. # belongs_to :manager # foreign key - manager_id
  244. # end
  245. #
  246. # === Many-to-many
  247. #
  248. # There are two ways to build a many-to-many relationship.
  249. #
  250. # The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so
  251. # there are two stages of associations.
  252. #
  253. # class Assignment < ActiveRecord::Base
  254. # belongs_to :programmer # foreign key - programmer_id
  255. # belongs_to :project # foreign key - project_id
  256. # end
  257. # class Programmer < ActiveRecord::Base
  258. # has_many :assignments
  259. # has_many :projects, :through => :assignments
  260. # end
  261. # class Project < ActiveRecord::Base
  262. # has_many :assignments
  263. # has_many :programmers, :through => :assignments
  264. # end
  265. #
  266. # For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
  267. # that has no corresponding model or primary key.
  268. #
  269. # class Programmer < ActiveRecord::Base
  270. # has_and_belongs_to_many :projects # foreign keys in the join table
  271. # end
  272. # class Project < ActiveRecord::Base
  273. # has_and_belongs_to_many :programmers # foreign keys in the join table
  274. # end
  275. #
  276. # Choosing which way to build a many-to-many relationship is not always simple.
  277. # If you need to work with the relationship model as its own entity,
  278. # use <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when
  279. # you never work directly with the relationship itself.
  280. #
  281. # == Is it a +belongs_to+ or +has_one+ association?
  282. #
  283. # Both express a 1-1 relationship. The difference is mostly where to place the foreign
  284. # key, which goes on the table for the class declaring the +belongs_to+ relationship.
  285. #
  286. # class User < ActiveRecord::Base
  287. # # I reference an account.
  288. # belongs_to :account
  289. # end
  290. #
  291. # class Account < ActiveRecord::Base
  292. # # One user references me.
  293. # has_one :user
  294. # end
  295. #
  296. # The tables for these classes could look something like:
  297. #
  298. # CREATE TABLE users (
  299. # id int(11) NOT NULL auto_increment,
  300. # account_id int(11) default NULL,
  301. # name varchar default NULL,
  302. # PRIMARY KEY (id)
  303. # )
  304. #
  305. # CREATE TABLE accounts (
  306. # id int(11) NOT NULL auto_increment,
  307. # name varchar default NULL,
  308. # PRIMARY KEY (id)
  309. # )
  310. #
  311. # == Unsaved objects and associations
  312. #
  313. # You can manipulate objects and associations before they are saved to the database, but
  314. # there is some special behavior you should be aware of, mostly involving the saving of
  315. # associated objects.
  316. #
  317. # You can set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
  318. # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
  319. # to +true+ will _always_ save the members, whereas setting it to +false+ will
  320. # _never_ save the members. More details about :autosave option is available at
  321. # autosave_association.rb .
  322. #
  323. # === One-to-one associations
  324. #
  325. # * Assigning an object to a +has_one+ association automatically saves that object and
  326. # the object being replaced (if there is one), in order to update their foreign
  327. # keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
  328. # * If either of these saves fail (due to one of the objects being invalid), an
  329. # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
  330. # cancelled.
  331. # * If you wish to assign an object to a +has_one+ association without saving it,
  332. # use the <tt>build_association</tt> method (documented below). The object being
  333. # replaced will still be saved to update its foreign key.
  334. # * Assigning an object to a +belongs_to+ association does not save the object, since
  335. # the foreign key field belongs on the parent. It does not save the parent either.
  336. #
  337. # === Collections
  338. #
  339. # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
  340. # saves that object, except if the parent object (the owner of the collection) is not yet
  341. # stored in the database.
  342. # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
  343. # fails, then <tt>push</tt> returns +false+.
  344. # * If saving fails while replacing the collection (via <tt>association=</tt>), an
  345. # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
  346. # cancelled.
  347. # * You can add an object to a collection without automatically saving it by using the
  348. # <tt>collection.build</tt> method (documented below).
  349. # * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
  350. # saved when the parent is saved.
  351. #
  352. # === Association callbacks
  353. #
  354. # Similar to the normal callbacks that hook into the life cycle of an Active Record object,
  355. # you can also define callbacks that get triggered when you add an object to or remove an
  356. # object from an association collection.
  357. #
  358. # class Project
  359. # has_and_belongs_to_many :developers, :after_add => :evaluate_velocity
  360. #
  361. # def evaluate_velocity(developer)
  362. # ...
  363. # end
  364. # end
  365. #
  366. # It's possible to stack callbacks by passing them as an array. Example:
  367. #
  368. # class Project
  369. # has_and_belongs_to_many :developers,
  370. # :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
  371. # end
  372. #
  373. # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
  374. #
  375. # Should any of the +before_add+ callbacks throw an exception, the object does not get
  376. # added to the collection. Same with the +before_remove+ callbacks; if an exception is
  377. # thrown the object doesn't get removed.
  378. #
  379. # === Association extensions
  380. #
  381. # The proxy objects that control the access to associations can be extended through anonymous
  382. # modules. This is especially beneficial for adding new finders, creators, and other
  383. # factory-type methods that are only used as part of this association.
  384. #
  385. # class Account < ActiveRecord::Base
  386. # has_many :people do
  387. # def find_or_create_by_name(name)
  388. # first_name, last_name = name.split(" ", 2)
  389. # find_or_create_by_first_name_and_last_name(first_name, last_name)
  390. # end
  391. # end
  392. # end
  393. #
  394. # person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson")
  395. # person.first_name # => "David"
  396. # person.last_name # => "Heinemeier Hansson"
  397. #
  398. # If you need to share the same extensions between many associations, you can use a named
  399. # extension module.
  400. #
  401. # module FindOrCreateByNameExtension
  402. # def find_or_create_by_name(name)
  403. # first_name, last_name = name.split(" ", 2)
  404. # find_or_create_by_first_name_and_last_name(first_name, last_name)
  405. # end
  406. # end
  407. #
  408. # class Account < ActiveRecord::Base
  409. # has_many :people, :extend => FindOrCreateByNameExtension
  410. # end
  411. #
  412. # class Company < ActiveRecord::Base
  413. # has_many :people, :extend => FindOrCreateByNameExtension
  414. # end
  415. #
  416. # If you need to use multiple named extension modules, you can specify an array of modules
  417. # with the <tt>:extend</tt> option.
  418. # In the case of name conflicts between methods in the modules, methods in modules later
  419. # in the array supercede those earlier in the array.
  420. #
  421. # class Account < ActiveRecord::Base
  422. # has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
  423. # end
  424. #
  425. # Some extensions can only be made to work with knowledge of the association's internals.
  426. # Extensions can access relevant state using the following methods (where +items+ is the
  427. # name of the association):
  428. #
  429. # * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
  430. # * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
  431. # * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
  432. # the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
  433. #
  434. # However, inside the actual extension code, you will not have access to the <tt>record</tt> as
  435. # above. In this case, you can access <tt>proxy_association</tt>. For example,
  436. # <tt>record.association(:items)</tt> and <tt>record.items.proxy_association</tt> will return
  437. # the same object, allowing you to make calls like <tt>proxy_association.owner</tt> inside
  438. # association extensions.
  439. #
  440. # === Association Join Models
  441. #
  442. # Has Many associations can be configured with the <tt>:through</tt> option to use an
  443. # explicit join model to retrieve the data. This operates similarly to a
  444. # +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
  445. # callbacks, and extra attributes on the join model. Consider the following schema:
  446. #
  447. # class Author < ActiveRecord::Base
  448. # has_many :authorships
  449. # has_many :books, :through => :authorships
  450. # end
  451. #
  452. # class Authorship < ActiveRecord::Base
  453. # belongs_to :author
  454. # belongs_to :book
  455. # end
  456. #
  457. # @author = Author.first
  458. # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
  459. # @author.books # selects all books by using the Authorship join model
  460. #
  461. # You can also go through a +has_many+ association on the join model:
  462. #
  463. # class Firm < ActiveRecord::Base
  464. # has_many :clients
  465. # has_many :invoices, :through => :clients
  466. # end
  467. #
  468. # class Client < ActiveRecord::Base
  469. # belongs_to :firm
  470. # has_many :invoices
  471. # end
  472. #
  473. # class Invoice < ActiveRecord::Base
  474. # belongs_to :client
  475. # end
  476. #
  477. # @firm = Firm.first
  478. # @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm
  479. # @firm.invoices # selects all invoices by going through the Client join model
  480. #
  481. # Similarly you can go through a +has_one+ association on the join model:
  482. #
  483. # class Group < ActiveRecord::Base
  484. # has_many :users
  485. # has_many :avatars, :through => :users
  486. # end
  487. #
  488. # class User < ActiveRecord::Base
  489. # belongs_to :group
  490. # has_one :avatar
  491. # end
  492. #
  493. # class Avatar < ActiveRecord::Base
  494. # belongs_to :user
  495. # end
  496. #
  497. # @group = Group.first
  498. # @group.users.collect { |u| u.avatar }.flatten # select all avatars for all users in the group
  499. # @group.avatars # selects all avatars by going through the User join model.
  500. #
  501. # An important caveat with going through +has_one+ or +has_many+ associations on the
  502. # join model is that these associations are *read-only*. For example, the following
  503. # would not work following the previous example:
  504. #
  505. # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
  506. # @group.avatars.delete(@group.avatars.last) # so would this
  507. #
  508. # If you are using a +belongs_to+ on the join model, it is a good idea to set the
  509. # <tt>:inverse_of</tt> option on the +belongs_to+, which will mean that the following example
  510. # works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association):
  511. #
  512. # @post = Post.first
  513. # @tag = @post.tags.build :name => "ruby"
  514. # @tag.save
  515. #
  516. # The last line ought to save the through record (a <tt>Taggable</tt>). This will only work if the
  517. # <tt>:inverse_of</tt> is set:
  518. #
  519. # class Taggable < ActiveRecord::Base
  520. # belongs_to :post
  521. # belongs_to :tag, :inverse_of => :taggings
  522. # end
  523. #
  524. # === Nested Associations
  525. #
  526. # You can actually specify *any* association with the <tt>:through</tt> option, including an
  527. # association which has a <tt>:through</tt> option itself. For example:
  528. #
  529. # class Author < ActiveRecord::Base
  530. # has_many :posts
  531. # has_many :comments, :through => :posts
  532. # has_many :commenters, :through => :comments
  533. # end
  534. #
  535. # class Post < ActiveRecord::Base
  536. # has_many :comments
  537. # end
  538. #
  539. # class Comment < ActiveRecord::Base
  540. # belongs_to :commenter
  541. # end
  542. #
  543. # @author = Author.first
  544. # @author.commenters # => People who commented on posts written by the author
  545. #
  546. # An equivalent way of setting up this association this would be:
  547. #
  548. # class Author < ActiveRecord::Base
  549. # has_many :posts
  550. # has_many :commenters, :through => :posts
  551. # end
  552. #
  553. # class Post < ActiveRecord::Base
  554. # has_many :comments
  555. # has_many :commenters, :through => :comments
  556. # end
  557. #
  558. # class Comment < ActiveRecord::Base
  559. # belongs_to :commenter
  560. # end
  561. #
  562. # When using nested association, you will not be able to modify the association because there
  563. # is not enough information to know what modification to make. For example, if you tried to
  564. # add a <tt>Commenter</tt> in the example above, there would be no way to tell how to set up the
  565. # intermediate <tt>Post</tt> and <tt>Comment</tt> objects.
  566. #
  567. # === Polymorphic Associations
  568. #
  569. # Polymorphic associations on models are not restricted on what types of models they
  570. # can be associated with. Rather, they specify an interface that a +has_many+ association
  571. # must adhere to.
  572. #
  573. # class Asset < ActiveRecord::Base
  574. # belongs_to :attachable, :polymorphic => true
  575. # end
  576. #
  577. # class Post < ActiveRecord::Base
  578. # has_many :assets, :as => :attachable # The :as option specifies the polymorphic interface to use.
  579. # end
  580. #
  581. # @asset.attachable = @post
  582. #
  583. # This works by using a type column in addition to a foreign key to specify the associated
  584. # record. In the Asset example, you'd need an +attachable_id+ integer column and an
  585. # +attachable_type+ string column.
  586. #
  587. # Using polymorphic associations in combination with single table inheritance (STI) is
  588. # a little tricky. In order for the associations to work as expected, ensure that you
  589. # store the base model for the STI models in the type column of the polymorphic
  590. # association. To continue with the asset example above, suppose there are guest posts
  591. # and member posts that use the posts table for STI. In this case, there must be a +type+
  592. # column in the posts table.
  593. #
  594. # class Asset < ActiveRecord::Base
  595. # belongs_to :attachable, :polymorphic => true
  596. #
  597. # def attachable_type=(sType)
  598. # super(sType.to_s.classify.constantize.base_class.to_s)
  599. # end
  600. # end
  601. #
  602. # class Post < ActiveRecord::Base
  603. # # because we store "Post" in attachable_type now :dependent => :destroy will work
  604. # has_many :assets, :as => :attachable, :dependent => :destroy
  605. # end
  606. #
  607. # class GuestPost < Post
  608. # end
  609. #
  610. # class MemberPost < Post
  611. # end
  612. #
  613. # == Caching
  614. #
  615. # All of the methods are built on a simple caching principle that will keep the result
  616. # of the last query around unless specifically instructed not to. The cache is even
  617. # shared across methods to make it even cheaper to use the macro-added methods without
  618. # worrying too much about performance at the first go.
  619. #
  620. # project.milestones # fetches milestones from the database
  621. # project.milestones.size # uses the milestone cache
  622. # project.milestones.empty? # uses the milestone cache
  623. # project.milestones(true).size # fetches milestones from the database
  624. # project.milestones # uses the milestone cache
  625. #
  626. # == Eager loading of associations
  627. #
  628. # Eager loading is a way to find objects of a certain class and a number of named associations.
  629. # This is one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100
  630. # posts that each need to display their author triggers 101 database queries. Through the
  631. # use of eager loading, the 101 queries can be reduced to 2.
  632. #
  633. # class Post < ActiveRecord::Base
  634. # belongs_to :author
  635. # has_many :comments
  636. # end
  637. #
  638. # Consider the following loop using the class above:
  639. #
  640. # Post.all.each do |post|
  641. # puts "Post: " + post.title
  642. # puts "Written by: " + post.author.name
  643. # puts "Last comment on: " + post.comments.first.created_on
  644. # end
  645. #
  646. # To iterate over these one hundred posts, we'll generate 201 database queries. Let's
  647. # first just optimize it for retrieving the author:
  648. #
  649. # Post.includes(:author).each do |post|
  650. #
  651. # This references the name of the +belongs_to+ association that also used the <tt>:author</tt>
  652. # symbol. After loading the posts, find will collect the +author_id+ from each one and load
  653. # all the referenced authors with one query. Doing so will cut down the number of queries
  654. # from 201 to 102.
  655. #
  656. # We can improve upon the situation further by referencing both associations in the finder with:
  657. #
  658. # Post.includes(:author, :comments).each do |post|
  659. #
  660. # This will load all comments with a single query. This reduces the total number of queries
  661. # to 3. More generally the number of queries will be 1 plus the number of associations
  662. # named (except if some of the associations are polymorphic +belongs_to+ - see below).
  663. #
  664. # To include a deep hierarchy of associations, use a hash:
  665. #
  666. # Post.includes(:author, {:comments => {:author => :gravatar}}).each do |post|
  667. #
  668. # That'll grab not only all the comments but all their authors and gravatar pictures.
  669. # You can mix and match symbols, arrays and hashes in any combination to describe the
  670. # associations you want to load.
  671. #
  672. # All of this power shouldn't fool you into thinking that you can pull out huge amounts
  673. # of data with no performance penalty just because you've reduced the number of queries.
  674. # The database still needs to send all the data to Active Record and it still needs to
  675. # be processed. So it's no catch-all for performance problems, but it's a great way to
  676. # cut down on the number of queries in a situation as the one described above.
  677. #
  678. # Since only one table is loaded at a time, conditions or orders cannot reference tables
  679. # other than the main one. If this is the case Active Record falls back to the previously
  680. # used LEFT OUTER JOIN based strategy. For example
  681. #
  682. # Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all
  683. #
  684. # This will result in a single SQL query with joins along the lines of:
  685. # <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
  686. # <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions
  687. # like this can have unintended consequences.
  688. # In the above example posts with no approved comments are not returned at all, because
  689. # the conditions apply to the SQL statement as a whole and not just to the association.
  690. # You must disambiguate column references for this fallback to happen, for example
  691. # <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not.
  692. #
  693. # If you do want eager load only some members of an association it is usually more natural
  694. # to include an association which has conditions defined on it:
  695. #
  696. # class Post < ActiveRecord::Base
  697. # has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true]
  698. # end
  699. #
  700. # Post.includes(:approved_comments)
  701. #
  702. # This will load posts and eager load the +approved_comments+ association, which contains
  703. # only those comments that have been approved.
  704. #
  705. # If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored,
  706. # returning all the associated objects:
  707. #
  708. # class Picture < ActiveRecord::Base
  709. # has_many :most_recent_comments, :class_name => 'Comment', :order => 'id DESC', :limit => 10
  710. # end
  711. #
  712. # Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
  713. #
  714. # When eager loaded, conditions are interpolated in the context of the model class, not
  715. # the model instance. Conditions are lazily interpolated before the actual model exists.
  716. #
  717. # Eager loading is supported with polymorphic associations.
  718. #
  719. # class Address < ActiveRecord::Base
  720. # belongs_to :addressable, :polymorphic => true
  721. # end
  722. #
  723. # A call that tries to eager load the addressable model
  724. #
  725. # Address.includes(:addressable)
  726. #
  727. # This will execute one query to load the addresses and load the addressables with one
  728. # query per addressable type.
  729. # For example if all the addressables are either of class Person or Company then a total
  730. # of 3 queries will be executed. The list of addressable types to load is determined on
  731. # the back of the addresses loaded. This is not supported if Active Record has to fallback
  732. # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
  733. # The reason is that the parent model's type is a column value so its corresponding table
  734. # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
  735. #
  736. # == Table Aliasing
  737. #
  738. # Active Record uses table aliasing in the case that a table is referenced multiple times
  739. # in a join. If a table is referenced only once, the standard table name is used. The
  740. # second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>.
  741. # Indexes are appended for any more successive uses of the table name.
  742. #
  743. # Post.joins(:comments)
  744. # # => SELECT ... FROM posts INNER JOIN comments ON ...
  745. # Post.joins(:special_comments) # STI
  746. # # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
  747. # Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
  748. # # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
  749. #
  750. # Acts as tree example:
  751. #
  752. # TreeMixin.joins(:children)
  753. # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
  754. # TreeMixin.joins(:children => :parent)
  755. # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
  756. # INNER JOIN parents_mixins ...
  757. # TreeMixin.joins(:children => {:parent => :children})
  758. # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
  759. # INNER JOIN parents_mixins ...
  760. # INNER JOIN mixins childrens_mixins_2
  761. #
  762. # Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
  763. #
  764. # Post.joins(:categories)
  765. # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
  766. # Post.joins(:categories => :posts)
  767. # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
  768. # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
  769. # Post.joins(:categories => {:posts => :categories})
  770. # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
  771. # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
  772. # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
  773. #
  774. # If you wish to specify your own custom joins using <tt>joins</tt> method, those table
  775. # names will take precedence over the eager associations:
  776. #
  777. # Post.joins(:comments).joins("inner join comments ...")
  778. # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
  779. # Post.joins(:comments, :special_comments).joins("inner join comments ...")
  780. # # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
  781. # INNER JOIN comments special_comments_posts ...
  782. # INNER JOIN comments ...
  783. #
  784. # Table aliases are automatically truncated according to the maximum length of table identifiers
  785. # according to the specific database.
  786. #
  787. # == Modules
  788. #
  789. # By default, associations will look for objects within the current module scope. Consider:
  790. #
  791. # module MyApplication
  792. # module Business
  793. # class Firm < ActiveRecord::Base
  794. # has_many :clients
  795. # end
  796. #
  797. # class Client < ActiveRecord::Base; end
  798. # end
  799. # end
  800. #
  801. # When <tt>Firm#clients</tt> is called, it will in turn call
  802. # <tt>MyApplication::Business::Client.find_all_by_firm_id(firm.id)</tt>.
  803. # If you want to associate with a class in another module scope, this can be done by
  804. # specifying the complete class name.
  805. #
  806. # module MyApplication
  807. # module Business
  808. # class Firm < ActiveRecord::Base; end
  809. # end
  810. #
  811. # module Billing
  812. # class Account < ActiveRecord::Base
  813. # belongs_to :firm, :class_name => "MyApplication::Business::Firm"
  814. # end
  815. # end
  816. # end
  817. #
  818. # == Bi-directional associations
  819. #
  820. # When you specify an association there is usually an association on the associated model
  821. # that specifies the same relationship in reverse. For example, with the following models:
  822. #
  823. # class Dungeon < ActiveRecord::Base
  824. # has_many :traps
  825. # has_one :evil_wizard
  826. # end
  827. #
  828. # class Trap < ActiveRecord::Base
  829. # belongs_to :dungeon
  830. # end
  831. #
  832. # class EvilWizard < ActiveRecord::Base
  833. # belongs_to :dungeon
  834. # end
  835. #
  836. # The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
  837. # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
  838. # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
  839. # Active Record doesn't know anything about these inverse relationships and so no object
  840. # loading optimization is possible. For example:
  841. #
  842. # d = Dungeon.first
  843. # t = d.traps.first
  844. # d.level == t.dungeon.level # => true
  845. # d.level = 10
  846. # d.level == t.dungeon.level # => false
  847. #
  848. # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
  849. # the same object data from the database, but are actually different in-memory copies
  850. # of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
  851. # Active Record about inverse relationships and it will optimise object loading. For
  852. # example, if we changed our model definitions to:
  853. #
  854. # class Dungeon < ActiveRecord::Base
  855. # has_many :traps, :inverse_of => :dungeon
  856. # has_one :evil_wizard, :inverse_of => :dungeon
  857. # end
  858. #
  859. # class Trap < ActiveRecord::Base
  860. # belongs_to :dungeon, :inverse_of => :traps
  861. # end
  862. #
  863. # class EvilWizard < ActiveRecord::Base
  864. # belongs_to :dungeon, :inverse_of => :evil_wizard
  865. # end
  866. #
  867. # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
  868. # in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
  869. #
  870. # There are limitations to <tt>:inverse_of</tt> support:
  871. #
  872. # * does not work with <tt>:through</tt> associations.
  873. # * does not work with <tt>:polymorphic</tt> associations.
  874. # * for +belongs_to+ associations +has_many+ inverse associations are ignored.
  875. #
  876. # == Deleting from associations
  877. #
  878. # === Dependent associations
  879. #
  880. # +has_many+, +has_one+ and +belongs_to+ associations support the <tt>:dependent</tt> option.
  881. # This allows you to specify that associated records should be deleted when the owner is
  882. # deleted.
  883. #
  884. # For example:
  885. #
  886. # class Author
  887. # has_many :posts, :dependent => :destroy
  888. # end
  889. # Author.find(1).destroy # => Will destroy all of the author's posts, too
  890. #
  891. # The <tt>:dependent</tt> option can have different values which specify how the deletion
  892. # is done. For more information, see the documentation for this option on the different
  893. # specific association types.
  894. #
  895. # === Delete or destroy?
  896. #
  897. # +has_many+ and +has_and_belongs_to_many+ associations have the methods <tt>destroy</tt>,
  898. # <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>.
  899. #
  900. # For +has_and_belongs_to_many+, <tt>delete</tt> and <tt>destroy</tt> are the same: they
  901. # cause the records in the join table to be removed.
  902. #
  903. # For +has_many+, <tt>destroy</tt> will always call the <tt>destroy</tt> method of the
  904. # record(s) being removed so that callbacks are run. However <tt>delete</tt> will either
  905. # do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
  906. # if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
  907. # The default strategy is <tt>:nullify</tt> (set the foreign keys to <tt>nil</tt>), except for
  908. # +has_many+ <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
  909. # the join records, without running their callbacks).
  910. #
  911. # There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that
  912. # it returns the association rather than the records which have been deleted.
  913. #
  914. # === What gets deleted?
  915. #
  916. # There is a potential pitfall here: +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>
  917. # associations have records in join tables, as well as the associated records. So when we
  918. # call one of these deletion methods, what exactly should be deleted?
  919. #
  920. # The answer is that it is assumed that deletion on an association is about removing the
  921. # <i>link</i> between the owner and the associated object(s), rather than necessarily the
  922. # associated objects themselves. So with +has_and_belongs_to_many+ and +has_many+
  923. # <tt>:through</tt>, the join records will be deleted, but the associated records won't.
  924. #
  925. # This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by_name('food'))</tt>
  926. # you would want the 'food' tag to be unlinked from the post, rather than for the tag itself
  927. # to be removed from the database.
  928. #
  929. # However, there are examples where this strategy doesn't make sense. For example, suppose
  930. # a person has many projects, and each project has many tasks. If we deleted one of a person's
  931. # tasks, we would probably not want the project to be deleted. In this scenario, the delete method
  932. # won't actually work: it can only be used if the association on the join model is a
  933. # +belongs_to+. In other situations you are expected to perform operations directly on
  934. # either the associated records or the <tt>:through</tt> association.
  935. #
  936. # With a regular +has_many+ there is no distinction between the "associated records"
  937. # and the "link", so there is only one choice for what gets deleted.
  938. #
  939. # With +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>, if you want to delete the
  940. # associated records themselves, you can always do something along the lines of
  941. # <tt>person.tasks.each(&:destroy)</tt>.
  942. #
  943. # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
  944. #
  945. # If you attempt to assign an object to an association that doesn't match the inferred
  946. # or specified <tt>:class_name</tt>, you'll get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
  947. #
  948. # == Options
  949. #
  950. # All of the association macros can be specialized through options. This makes cases
  951. # more complex than the simple and guessable ones possible.
  952. module ClassMethods
  953. # Specifies a one-to-many association. The following methods for retrieval and query of
  954. # collections of associated objects will be added:
  955. #
  956. # [collection(force_reload = false)]
  957. # Returns an array of all the associated objects.
  958. # An empty array is returned if none are found.
  959. # [collection<<(object, ...)]
  960. # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
  961. # Note that this operation instantly fires update sql without waiting for the save or update call on the
  962. # parent object.
  963. # [collection.delete(object, ...)]
  964. # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
  965. # Objects will be in addition destroyed if they're associated with <tt>:dependent => :destroy</tt>,
  966. # and deleted if they're associated with <tt>:dependent => :delete_all</tt>.
  967. #
  968. # If the <tt>:through</tt> option is used, then the join records are deleted (rather than
  969. # nullified) by default, but you can specify <tt>:dependent => :destroy</tt> or
  970. # <tt>:dependent => :nullify</tt> to override this.
  971. # [collection=objects]
  972. # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
  973. # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
  974. # direct.
  975. # [collection_singular_ids]
  976. # Returns an array of the associated objects' ids
  977. # [collection_singular_ids=ids]
  978. # Replace the collection with the objects identified by the primary keys in +ids+. This
  979. # method loads the models and calls <tt>collection=</tt>. See above.
  980. # [collection.clear]
  981. # Removes every object from the collection. This destroys the associated objects if they
  982. # are associated with <tt>:dependent => :destroy</tt>, deletes them directly from the
  983. # datab