Ruby on Rails
ActiveRecord Associations
Ricerca…
appartiene a
A belongs_to
association imposta una connessione one-to-one con un altro modello, quindi ogni istanza del modello dichiarante "appartiene a" un'istanza dell'altro modello.
Ad esempio, se l'applicazione include utenti e post e ogni post può essere assegnato esattamente a un utente, dichiarerai il modello di post in questo modo:
class Post < ApplicationRecord
belongs_to :user
end
Nella tua struttura tabella potresti avere
create_table "posts", force: :cascade do |t|
t.integer "user_id", limit: 4
end
Ha uno
has_one
imposta una connessione one-to-one con un altro modello, ma con semantica diversa. Questa associazione indica che ogni istanza di un modello contiene o possiede un'istanza di un altro modello.
Ad esempio, se ogni utente nella tua applicazione ha un solo account, dichiareresti il modello utente in questo modo:
class User < ApplicationRecord
has_one :account
end
In Active Record, quando si ha una relazione has_one
, il record attivo garantisce che l'unico record esista con la chiave esterna.
Qui nel nostro esempio: nella tabella degli account, può esserci un solo record con un id utente particolare. Se si tenta di associare un altro account per lo stesso utente, rende la chiave esterna della voce precedente come null (rendendola orfana) e ne crea automaticamente una nuova. Rende nullo la voce precedente anche se il salvataggio fallisce perché la nuova voce mantenga la coerenza.
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]
ha molti
has_many
indica una connessione uno-a-molti con un altro modello. Questa associazione generalmente si trova sull'altro lato di un'associazione_part_di.
Questa associazione indica che ogni istanza del modello ha zero o più istanze di un altro modello.
Ad esempio, in un'applicazione contenente utenti e post, il modello utente potrebbe essere dichiarato in questo modo:
class User < ApplicationRecord
has_many :posts
end
La struttura della tabella di Post
rimarrebbe la stessa come nel belongs_to
esempio; al contrario, l' User
non richiederebbe alcuna modifica dello schema.
Se si desidera ottenere l'elenco di tutti i post pubblicati per l' User
, è possibile aggiungere quanto segue (ovvero è possibile aggiungere ambiti agli oggetti di associazione):
class User < ApplicationRecord
has_many :published_posts, -> { where("posts.published IS TRUE") }, class_name: "Post"
end
Associazione polimorfica
Questo tipo di associazione consente ad un modello di ActiveRecord di appartenere a più di un tipo di record del modello. Esempio comune:
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
Senza questa associazione, avresti tutte queste chiavi esterne nella tua tabella Indirizzi ma solo tu avresti mai un valore per una di esse perché un indirizzo, in questo scenario, può appartenere solo a una entità (Umana o Azienda). Ecco come apparirà:
class Address < ActiveRecord::Base
belongs_to :human
belongs_to :company
end
L'has_many: attraverso l'associazione
A has_many :through
associazione viene spesso utilizzato per impostare una connessione many-to-many
con un altro modello. Questa associazione indica che il modello di dichiarazione può essere abbinato a zero o più istanze di un altro modello procedendo attraverso un terzo modello.
Ad esempio, si consideri una pratica medica in cui i pazienti fanno appuntamenti per vedere i medici. Le dichiarazioni di associazione pertinenti potrebbero assomigliare a questo:
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: attraverso l'associazione
A has_one :through
associazione imposta una connessione one-to-one
con un altro modello. Questa associazione indica che il modello di dichiarazione può essere abbinato a un'istanza di un altro modello procedendo attraverso un terzo modello.
Ad esempio, se ogni supplier
ha un account
e ogni account è associato a una cronologia dell'account, il modello del fornitore potrebbe essere simile al seguente:
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'associazione has_and_belongs_to_many
has_and_belongs_to_many
crea una connessione diretta many-to-many
con un altro modello, senza alcun modello has_and_belongs_to_many
.
Ad esempio, se l'applicazione include assemblies
e parts
, con ciascun assieme con molte parti e ciascuna parte che appare in molti assiemi, è possibile dichiarare i modelli in questo modo:
class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
Associazione autoreferenziale
L'associazione autoreferenziale viene utilizzata per associare un modello a se stesso. L'esempio più frequente sarebbe, per gestire l'associazione tra un amico e il suo seguace.
ex.
rails g model friendship user_id:references friend_id:integer
ora puoi associare modelli come;
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
e l'altro modello sarà simile;
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User"
end