Active Record Associations
Bài đăng này đã không được cập nhật trong 7 năm
Giới thiệu
Trong rails, association là liên kết giữa 2 model với nhau. Association giúp cho việc truy vấn dễ dàng và làm cho code ngắn gọn, đơn giản hơn rất nhiều. Giả sử ta có 2 models là User và Picture, giả sử 1 user có nhiều picture và 1 picture chỉ thuộc 1 user. Khi đó ta sẽ khai báo trong model User và Picture như sau:
class User < ApplicationRecord
has_many :pictures
end
class Picture < ApplicationRecord
belongs_to :user
end
Khi chúng ta đã có 1 user hay 1 picture bất kỳ, việc tìm ra các pictures hay user của nó rất dễ dàng, bằng dòng code như sau:
user = User.first #giả sử user tồn tại
pictures = user.pictures
hoặc:
picture = Picture.first #giả sử picture tồn tại
user = picture.user
Các loại Associations
Rails có hỗ trợ 6 loại như sau:
- belongs_to
- has_one
- has_many
- has_many :through
- has_one :through
- has_and_belongs_to_many
The belongs_to association
belongs_to thiết lập kết nối one-to-one (1-1) giữa model này với model khác. Giả sử như ví dụ ở trên ta khai báo trong model Picture
belongs_to :user
Đặc biệt, đối với belongs_to chúng ta cần khai báo khóa ngoại cho bảng. Giả sử trong trường hợp này, chúng ta cần có khóa ngoại user_id trong bảng pictures.
class CreateTables < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.timestamps
end
create_table :pictures do |t|
t.belongs_to :users, index: true
t.string :name
t.timestamps
end
end
end
The has_one Association
has_one cũng thiết lập kết nối one-to-one với 1 model khác, nhưng nó khác nhau về mặt ý nghĩa. Mối quan hệ này cho thấy răng 1 đối tượng của model này sở hữu 1 đối tượng của model khác. Ví dụ như ta có 2 đối tượng của 2 models là user và account, mỗi user chỉ có một account. Chúng ta sẽ khai báo như sau:
class User < ApplicationRecord
has_one :account
end
class CreateTables < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.timestamps
end
create_table :accounts do |t|
t.belongs_to :user, index: true, unique: true, foreign_key: true
t.string :account_number
t.timestamps
end
end
end
Tùy vào trường hợp và mục đích sử dụng, chúng ta có thể khai báo unique hay không.
The has_many Association
has_many thiết lập kết nối one-to-many với 1 model khác. Chúng ta sẽ thường thấy has_many ở model kia trong mối quan hệ belongs_to. Mối quan hệ này chỉ ra răng một đối tượng của model này có thể có 0 hoặc nhiều đối tượng của một model khác. Ví dụ như ở trên, ta có một user sẽ có nhiều pictures, ta sẽ khai báo như sau:
class User < ApplicationRecord
has_many :pictures
end
class Picture < ApplicationRecord
belongs_to :user
end
Ở model Picture, chúng ta có khai báo quan hệ belongs_to vậy nên chúng ta cần phải thêm khóa ngoại user_id cho bảng pictures.
class CreateTables < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.timestamps
end
create_table :pictures do |t|
t.belongs_to :user, index: true
t.string :name
t.timestamps
end
end
end
The has_many :through Association
has_many:through association thường được sử dụng để thiết lập mối quan hệ many-to-many (n-n) giữa 2 model với nhau. Giả sử ta có 2 model Student và Subject, trong đó 1 học sinh có thể học nhiều môn và 1 môn học có thể có nhiều học sinh học. Từ đó ta có quan hệ giữa Student và Subject là n-n. Thông thường, đối với quan hệ n-n, chúng ta cần tạo ra 1 model thứ 3 ở giữa để trở thành 2 mối quan hệ 1-n. Trong trường hợp này, chúng ta sẽ có model thứ 3 chính là Result và khai báo trong các model như sau:
class Student < ApplicationRecord
has_many :results
has_many :subjects, through: :results
end
class Result < ApplicationRecord
belongs_to :student
belongs_to :subject
end
class Subject < ApplicationRecord
has_many :results
has_many :students, through: :results
end
The has_one :through Association
has_one :through association thiết lập quan hệ one-to-one giữa model này với model khác. Quan hệ này chỉ ra mối quan hệ 1-1 giữa model này với 1 model khác thông qua 1 model thứ 3. Giả sử nếu như chúng ta có model Supplier sẽ có quan hệ 1-1 với model Account và model Account có quan hệ 1-1 với AccountHistory. Từ đó, thông qua model Account chúng ta sẽ có ứng với 1 Supplier sẽ có 1 AccountHistory. Và chúng ta khai báo trong model như sau:
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
The has_and_belongs_to_many Association
has_and_belongs_to_many tạo ra một quan hệ n-n trực tiếp mà không có sự can thiệp của 1 model khác. Giả sử chúng ta có model Assembly và Part. Ứng với 1 assembly có nhiều parts và 1 part có nhiều assemblies. Chúng ta sẽ khai báo trong model như sau:
class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
Kết
Trên đây mình giới thiệu với các bạn về mối quan hệ giữa các ActiveRecord trong Rails, tất nhiên vẫn còn nhiều thiếu sót và hạn chế, hy vọng giúp ích phần nào và các bạn tiếp cận Rails dễ dàng hơn.
Tham khảo:
All rights reserved