Rails supports six types of associations:
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
belongs_to
Sets up a one-to-one connection with another model,
Each
instance of the declaring model "belongs to" one instance of the other
model.
For example, if your application includes customers and orders,
and each order can be assigned to exactly one customer
:
class CreateOrders < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name
t.timestamps
end
create_table :orders do |t|
t.belongs_to :customer
t.datetime :order_date
t.timestamps
end
end
end
| |
has_one
sets up a one-to-one connection with another model
each instance of a model contains or possesses one instance of another model.
class CreateSuppliers < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
t.timestamps
end
create_table :accounts do |t|
t.belongs_to :supplier
t.string :account_number
t.timestamps
end
end
end
| |
has_many
Indicates a one-to-many connection with another model.
Often found on the "other side" of a
belongs_to
association.
each instance of the model
has zero or more instances of another model.
For example, in an
application containing customers and orders, the customer model could be declared like this:
class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name
t.timestamps
end
create_table :orders do |t|
t.belongs_to :customer
t.datetime :order_date
t.timestamps
end
end
end
| The name of the other model is pluralized when declaring a has_many association. |
has_many :through
Used to set up a many-to-many connection with another model.
The declaring model can be matched with zero
or more instances of another model by proceeding
through a
third model.
For example, consider a medical practice where patients
make appointments to see physicians. The relevant association
declarations could look like this:
class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
t.timestamps
end
create_table :patients do |t|
t.string :name
t.timestamps
end
create_table :appointments do |t|
t.belongs_to :physician
t.belongs_to :patient
t.datetime :appointment_date
t.timestamps
end
end
end
| |
The collection of join models can be managed via the API. For example, if you assign
physician.patients = patients
new join models are created for newly associated objects, and if some are gone their rows are deleted.
Automatic deletion of join models is direct, no destroy callbacks are triggered.
"shortcuts" through nested has_many associations.
For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document. You could set that up this way:
class Document < ActiveRecord::Base
has_many :sections
has_many :paragraphs, through: :sections
end
class Section < ActiveRecord::Base
belongs_to :document
has_many :paragraphs
end
class Paragraph < ActiveRecord::Base
belongs_to :section
end
With through: :sections specified, Rails will now understand:
@document.paragraphs
has_one :through
sets up a one-to-one connection with another model.
The declaring model can be matched with one instance of another model by proceeding
through a third model.
For example, if each supplier has one account, and each account is associated with one account history, then the
supplier model could look like this:
class CreateAccountHistories < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
t.timestamps
end
create_table :accounts do |t|
t.belongs_to :supplier
t.string :account_number
t.timestamps
end
create_table :account_histories do |t|
t.belongs_to :account
t.integer :credit_rating
t.timestamps
end
end
end
| |
has_and_belongs_to_many
creates a direct many-to-many connection with another model, with no
intervening model.
For example, if your application includes assemblies
and parts, with each assembly having many parts and each part appearing
in many assemblies, you could declare the models this way:
class CreateAssembliesAndParts < ActiveRecord::Migration
def change
create_table :assemblies do |t|
t.string :name
t.timestamps
end
create_table :parts do |t|
t.string :part_number
t.timestamps
end
create_table :assemblies_parts do |t|
t.belongs_to :assembly
t.belongs_to :part
end
end
end
| |