Ruby on Rails
Associations ActiveRecord
Recherche…
appartient à
Une association belongs_to
établit une connexion un-à-un avec un autre modèle, de sorte que chaque instance du modèle déclarant "appartient à" une instance de l'autre modèle.
Par exemple, si votre application inclut des utilisateurs et des publications, et que chaque publication peut être affectée à un seul utilisateur, vous devez déclarer le post-modèle de la manière suivante:
class Post < ApplicationRecord
belongs_to :user
end
Dans votre structure de table, vous pourriez alors avoir
create_table "posts", force: :cascade do |t|
t.integer "user_id", limit: 4
end
en a un
Une association has_one
établit une connexion un-à-un avec un autre modèle, mais avec une sémantique différente. Cette association indique que chaque instance d'un modèle contient ou possède une instance d'un autre modèle.
Par exemple, si chaque utilisateur de votre application ne possède qu'un seul compte, vous devez déclarer le modèle d'utilisateur comme suit:
class User < ApplicationRecord
has_one :account
end
Dans Active Record, lorsque vous avez une relation has_one
, l'enregistrement actif garantit que le seul enregistrement existe avec la clé étrangère.
Ici, dans notre exemple: Dans la table des comptes, il ne peut y avoir qu'un seul enregistrement avec un user_id particulier. Si vous essayez d'associer un compte supplémentaire pour le même utilisateur, la clé étrangère de l'entrée précédente devient null (ce qui la rend orpheline) et en crée une nouvelle automatiquement. Cela rend l'entrée précédente nulle même si la sauvegarde échoue pour que la nouvelle entrée conserve sa cohérence.
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]
a beaucoup
Une association has_many
indique une connexion un-à-plusieurs avec un autre modèle. Cette association est généralement située de l’autre côté de l’association Appartie à.
Cette association indique que chaque instance du modèle a zéro ou plusieurs instances d'un autre modèle.
Par exemple, dans une application contenant des utilisateurs et des publications, le modèle d’utilisateur peut être déclaré comme suit:
class User < ApplicationRecord
has_many :posts
end
La structure de la table de Post
resterait la même que dans l’application belongs_to
; en revanche, l' User
ne nécessiterait aucune modification de schéma.
Si vous souhaitez obtenir la liste de tous les messages publiés pour l' User
, vous pouvez ajouter les éléments suivants (vous pouvez ajouter des étendues à vos objets d'association):
class User < ApplicationRecord
has_many :published_posts, -> { where("posts.published IS TRUE") }, class_name: "Post"
end
Association polymorphe
Ce type d'association permet à un modèle ActiveRecord d'appartenir à plus d'un type d'enregistrement de modèle. Exemple commun:
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
Sans cette association, vous auriez toutes ces clés étrangères dans votre table Address, mais vous ne pourriez jamais avoir une valeur pour l'une d'entre elles car une adresse, dans ce scénario, ne peut appartenir qu'à une seule entité (humaine ou société). Voici à quoi ça ressemblerait:
class Address < ActiveRecord::Base
belongs_to :human
belongs_to :company
end
Le has_many: par association
Une association has_many :through
est souvent utilisée pour établir une connexion many-to-many
avec un autre modèle. Cette association indique que le modèle déclarant peut correspondre à zéro ou plusieurs instances d'un autre modèle en passant par un troisième modèle.
Par exemple, considérons un cabinet médical où les patients prennent rendez-vous pour consulter un médecin. Les déclarations d'association pertinentes pourraient ressembler à ceci:
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
Le has_one: par association
Une association has_one :through
configure one-to-one
connexion one-to-one
avec un autre modèle. Cette association indique que le modèle déclarant peut être associé à une instance d'un autre modèle en passant par un troisième modèle.
Par exemple, si chaque supplier
possède un account
et que chaque compte est associé à un historique de compte, le modèle de fournisseur peut alors ressembler à ceci:
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
L'association has_and_belongs_to_many
Une association has_and_belongs_to_many
crée une connexion directe many-to-many
avec un autre modèle, sans modèle intermédiaire.
Par exemple, si votre application comprend des assemblies
et des parts
, chaque assemblage comportant de nombreuses pièces et chaque pièce apparaissant dans de nombreux assemblages, vous pouvez déclarer les modèles de cette manière:
class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
Association auto-référentielle
L'association autoréférentielle est utilisée pour associer un modèle à lui-même. L'exemple le plus fréquent serait de gérer l'association entre un ami et son suiveur.
ex.
rails g model friendship user_id:references friend_id:integer
maintenant vous pouvez associer des modèles comme;
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
et l'autre modèle ressemblera;
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User"
end