Ruby on Rails
Ассоциации ActiveRecord
Поиск…
принадлежит
А ассоциация belongs_to
устанавливает соединение «один к одному» с другой моделью, поэтому каждый экземпляр объявляющей модели «принадлежит» одному экземпляру другой модели.
Например, если ваше приложение включает пользователей и сообщения, и каждый пост может быть назначен только одному пользователю, вы должны объявить модель сообщения следующим образом:
class Post < ApplicationRecord
belongs_to :user
end
В вашей структуре таблицы вы можете
create_table "posts", force: :cascade do |t|
t.integer "user_id", limit: 4
end
has_one
has_one
устанавливает соединение «один к одному» с другой моделью, но с другой семантикой. Эта ассоциация указывает, что каждый экземпляр модели содержит или обладает одним экземпляром другой модели.
Например, если каждый пользователь в вашем приложении имеет только одну учетную запись, вы должны объявить модель пользователя следующим образом:
class User < ApplicationRecord
has_one :account
end
В Active Record, когда у вас есть отношение has_one
, активная запись гарантирует, что существует только одна запись с внешним ключом.
Здесь в нашем примере: в таблице учетных записей может быть только одна запись с определенным user_id. Если вы пытаетесь связать еще одну учетную запись для одного и того же пользователя, это делает внешний ключ предыдущей записи как null (делая ее сиротой) и автоматически создает новую. Это делает предыдущую запись нулевой, даже если сохранение не позволяет новой записи поддерживать согласованность.
user = User.first
user.build_account(name: "sample")
user.save [Saves it successfully, and creates an entry in accounts table with user_id 1]
user.build_account(name: "sample1") [automatically makes the previous entry's foreign key null]
user.save [creates the new account with name sample 1 and user_id 1]
имеет много
Связь has_many
указывает на соединение «один ко многим» с другой моделью. Эта ассоциация, как правило, расположена на другой стороне ассоциации belongs_to.
Эта ассоциация указывает, что каждый экземпляр модели имеет ноль или более экземпляров другой модели.
Например, в приложении, содержащем пользователя и сообщения, модель пользователя может быть объявлена следующим образом:
class User < ApplicationRecord
has_many :posts
end
Структура таблицы Post
будет оставаться такой же, как в примере belongs_to
; в отличие от этого, User
не будет требовать каких-либо изменений схемы.
Если вы хотите получить список всех опубликованных сообщений для User
, то вы можете добавить следующее (например, вы можете добавлять области к объектам ассоциации):
class User < ApplicationRecord
has_many :published_posts, -> { where("posts.published IS TRUE") }, class_name: "Post"
end
Полиморфная ассоциация
Этот тип ассоциации позволяет модели ActiveRecord принадлежать более чем одному типу записи модели. Общий пример:
class Human < ActiveRecord::Base
has_one :address, :as => :addressable
end
class Company < ActiveRecord::Base
has_one :address, :as => :addressable
end
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
end
Без этой ассоциации у вас будут все эти внешние ключи в вашей таблице адресов, но у вас будет только значение для одного из них, потому что адрес в этом сценарии может принадлежать только одному объекту (человеку или компании). Вот как это будет выглядеть:
class Address < ActiveRecord::Base
belongs_to :human
belongs_to :company
end
Has_many: через ассоциацию
A has_many :through
объединение часто используется для установления соединения « many-to-many
с другой моделью. Эта ассоциация указывает, что модель объявления может быть сопоставлена с нулем или более экземплярами другой модели, пройдя через третью модель.
Например, рассмотрите медицинскую практику, когда пациенты назначают свидание врачам. Соответствующие декларации ассоциаций могут выглядеть так:
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
Has_one: через ассоциацию
A has_one :through
ассоциацию устанавливает соединение « one-to-one
с другой моделью. Эта ассоциация указывает, что модель объявления может быть сопоставлена с одним экземпляром другой модели, пройдя через третью модель.
Например, если у каждого supplier
есть одна account
, и каждая учетная запись связана с одной учетной записью, то модель поставщика может выглядеть так:
class Supplier < ApplicationRecord
has_one :account
has_one :account_history, through: :account
end
class Account < ApplicationRecord
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ApplicationRecord
belongs_to :account
end
Ассоциация has_and_belongs_to_many
has_and_belongs_to_many
создает прямое соединение « many-to-many
с другой моделью, без промежуточной модели.
Например, если ваше приложение содержит assemblies
и parts
, каждая сборка имеет много частей и каждая часть, отображаемая во многих сборках, вы можете объявить модели таким образом:
class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
Ассоциация самореференций
Самореференциальная ассоциация используется для сопоставления модели с самим собой. Наиболее частым примером могло бы быть управление ассоциацией между другом и его последователем.
ех.
rails g model friendship user_id:references friend_id:integer
теперь вы можете ассоциировать такие модели;
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
end
и другая модель будет выглядеть;
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User"
end