instance method has_many

Ruby on Rails 2.3.18

Since v2.2.3

Available in: v2.2.3 v2.3.18 v3.0.20 v3.1.12 v3.2.22.5 v4.0.13 v4.1.16 v4.2.9 v5.2.8.1 v6.0.6 v6.1.7.10 v7.0.10 v7.1.6 v7.2.3 v8.0.4 v8.1.2

Signature

has_many(association_id, options = {}, &extension)

Specifies a one-to-many association. The following methods for retrieval and query of collections of associated objects will be added:

collection(force_reload = false)

Returns an array of all the associated objects. An empty array is returned if none are found.

collection<<(object, …)

Adds one or more objects to the collection by setting their foreign keys to the collection’s primary key.

collection.delete(object, …)

Removes one or more objects from the collection by setting their foreign keys to NULL. Objects will be in addition destroyed if they’re associated with :dependent => :destroy, and deleted if they’re associated with :dependent => :delete_all.

collection=objects

Replaces the collections content by deleting and adding objects as appropriate.

collection_singular_ids

Returns an array of the associated objects’ ids

collection_singular_ids=ids

Replace the collection with the objects identified by the primary keys in ids

collection.clear

Removes every object from the collection. This destroys the associated objects if they are associated with :dependent => :destroy, deletes them directly from the database if :dependent => :delete_all, otherwise sets their foreign keys to NULL.

collection.empty?

Returns true if there are no associated objects.

collection.size

Returns the number of associated objects.

collection.find(…)

Finds an associated object according to the same rules as ActiveRecord::Base.find.

collection.exists?(…)

Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::Base.exists?.

collection.build(attributes = {}, …)

Returns one or more new objects of the collection type that have been instantiated with attributes and linked to this object through a foreign key, but have not yet been saved. Note: This only works if an associated object already exists, not if it’s nil!

collection.create(attributes = {})

Returns a new object of the collection type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation). Note: This only works if an associated object already exists, not if it’s nil!

(Note: collection is replaced with the symbol passed as the first argument, so has_many :clients would add among others clients.empty?.)

Example

Example: A Firm class declares has_many :clients, which will add:

  • Firm#clients (similar to Clients.find :all, :conditions => ["firm_id = ?", id])

  • Firm#clients<<

  • Firm#clients.delete

  • Firm#clients=

  • Firm#client_ids

  • Firm#client_ids=

  • Firm#clients.clear

  • Firm#clients.empty? (similar to firm.clients.size == 0)

  • Firm#clients.size (similar to Client.count "firm_id = #{id}")

  • Firm#clients.find (similar to Client.find(id, :conditions => "firm_id = #{id}"))

  • Firm#clients.exists?(:name => 'ACME') (similar to Client.exists?(:name => 'ACME', :firm_id => firm.id))

  • Firm#clients.build (similar to Client.new("firm_id" => id))

  • Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c)

The declaration can also include an options hash to specialize the behavior of the association.

Supported options

:class_name

Specify the class name of the association. Use it only if that name can’t be inferred from the association name. So has_many :products will by default be linked to the Product class, but if the real class name is SpecialProduct, you’ll have to specify it with this option.

:conditions

Specify the conditions that the associated objects must meet in order to be included as a WHERE SQL fragment, such as price > 5 AND name LIKE 'B%'. Record creations from the association are scoped if a hash is used. has_many :posts, :conditions => {:published => true} will create published posts with @blog.posts.create or @blog.posts.build.

:order

Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, such as last_name, first_name DESC.

:foreign_key

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and “_id” suffixed. So a Person class that makes a has_many association will use “person_id” as the default :foreign_key.

:primary_key

Specify the method that returns the primary key used for the association. By default this is id.

:dependent

If set to :destroy all the associated objects are destroyed alongside this object by calling their destroy method. If set to :delete_all all associated objects are deleted without calling their destroy method. If set to :nullify all associated objects’ foreign keys are set to NULL without calling their save callbacks. Warning: This option is ignored when also using the :through option.

:finder_sql

Specify a complete SQL statement to fetch the association. This is a good way to go for complex associations that depend on multiple tables. Note: When this option is used, find_in_collection is not added.

:counter_sql

Specify a complete SQL statement to fetch the size of the association. If :finder_sql is specified but not :counter_sql, :counter_sql will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM.

:extend

Specify a named module for extending the proxy. See “Association extensions”.

:include

Specify second-order associations that should be eager loaded when the collection is loaded.

:group

An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.

:having

Combined with :group this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause.

:limit

An integer determining the limit on the number of rows that should be returned.

:offset

An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.

:select

By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.

:as

Specifies a polymorphic interface (See belongs_to).

:through

Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key are ignored, as the association uses the source reflection. You can only use a :through query through a belongs_to has_one or has_many association on the join model.

:source

Specifies the source association name used by has_many :through queries. Only use it if the name cannot be inferred from the association. has_many :subscribers, :through => :subscriptions will look for either :subscribers or :subscriber on Subscription, unless a :source is given.

:source_type

Specifies type of the source association used by has_many :through queries where the source association is a polymorphic belongs_to.

:uniq

If true, duplicates will be omitted from the collection. Useful in conjunction with :through.

:readonly

If true, all the associated objects are readonly through the association.

:validate

If false, don’t validate the associated objects when saving the parent object. true by default.

:autosave

If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default.

Option examples:

has_many :comments, :order => "posted_on"
has_many :comments, :include => :author
has_many :people, :class_name => "Person", :conditions => "deleted = 0", :order => "name"
has_many :tracks, :order => "position", :dependent => :destroy
has_many :comments, :dependent => :nullify
has_many :tags, :as => :taggable
has_many :reports, :readonly => true
has_many :subscribers, :through => :subscriptions, :source => :user
has_many :subscribers, :class_name => "Person", :finder_sql =>
    'SELECT DISTINCT people.* ' +
    'FROM people p, post_subscriptions ps ' +
    'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' +
    'ORDER BY p.first_name'

Parameters

association_id req
options opt = {}
extension block
Source
# File activerecord/lib/active_record/associations.rb, line 828
      def has_many(association_id, options = {}, &extension)
        reflection = create_has_many_reflection(association_id, options, &extension)
        configure_dependency_for_has_many(reflection)
        add_association_callbacks(reflection.name, reflection.options)

        if options[:through]
          collection_accessor_methods(reflection, HasManyThroughAssociation)
        else
          collection_accessor_methods(reflection, HasManyAssociation)
        end
      end

Defined in activerecord/lib/active_record/associations.rb line 828 · View on GitHub · Improve this page · Find usages on GitHub

Defined in ActiveRecord::Associations::ClassMethods

Type at least 2 characters to search.

↑↓ navigate · open · esc close