07/09/2018, 17:51

Association trong Rails - Part 1 - Tạo association

Association là cách tạo ra ràng buộc giữa các model trong ứng dụng tương tự như các bảng trong database. Liên kết 1 - 1 Ví dụ ta có 2 bảng là users và accounts. Một user chỉ được có duy nhất 1 tài khoản ngân hàng và một tài khoản ngân hàng chỉ thuộc về 1 user nhất định, vậy để tạo association ...

Association là cách tạo ra ràng buộc giữa các model trong ứng dụng tương tự như các bảng trong database.

Liên kết 1 - 1

Ví dụ ta có 2 bảng là users và accounts. Một user chỉ được có duy nhất 1 tài khoản ngân hàng và một tài khoản ngân hàng chỉ thuộc về 1 user nhất định, vậy để tạo association cho 2 model này, ta sẽ khai báo trong 2 model như sau:

# app/models/user.rb
class User < ApplicationRecord
  has_one :account
end
# app/models/account.rb
class Account < ApplicationRecord
  belongs_to :user
end

Việc làm trên sẽ định nghĩa rằng mỗi đối tượng @user thuộc model User sẽ chỉ sở hữu một đối tượng @user.account thuộc model Account và mỗi đối tượng @account thuộc model Account chỉ thuộc về 1 đối tượng @account.user thuộc model User.

Liên kết 1 - n

Ví dụ ta có 2 bảng là users và tickets. Một user có thể có nhiều ticket và mỗi ticket chỉ thuộc về 1 user nào đó, vậy để tạo association cho 2 model này, ta sẽ khai báo trong 2 model như sau:

# app/models/user.rb
class User < ApplicationRecord
  has_many :tickets
end
# app/models/ticket.rb
class Ticket < ApplicationRecord
  belongs_to :user
end

Việc làm trên sẽ định nghĩa rằng mỗi đối tượng @user thuộc model User sẽ sở hữu nhiều đối tượng @user.tickets thuộc model Ticket và mỗi đối tượng @ticket thuộc model Ticket chỉ thuộc về 1 đối tượng @ticket.user thuộc model User.

Liên kết n - n

Ví dụ ta có 2 bảng là invoices và products được nối với nhau qua bảng invoice_details. Mỗi invoice có thể có nhiều invoice_details và mỗi product có thể có trong nhiều invoice_details.

Có 2 cách để tạo liên kết n - n, đó là sử dụng has_many :through và has_and_belongs_to_many.

Cách 1: Dùng has_many :through

# app/models/invoice_detail.rb
class InvoiceDetail < ApplicationRecord
  belongs_to :invoice
  belongs_to :product
end
# app/models/invoice.rb
class Invoice < ApplicationRecord
  has_many :invoice_details
  has_many :products, through: :invoice_details
end
# app/models/product.rb
class Product < ApplicationRecord
  has_many :invoice_details
  has_many :invoices, through: :invoice_details
end

Việc làm trên sẽ định nghĩa rằng mỗi đối tượng @invoice_detail thuộc model InvoiceDetail sẽ chỉ thuộc về một đối tượng @invoice_detail.invoice thuộc model Invoice và thuộc về một đối tượng @invoice_detail.product thuộc model Product, mỗi đối tượng @invoice thuộc model Invoice sở hữu nhiều đối tượng @invoice.invoice_details và @invoice.products, mỗi đối tượng @product thuộc model Product sở hữu nhiều đối tượng @product.invoice_details và @product.invoices.

Cách 2: Dùng has_and_belongs_to_many

# app/models/invoice.rb
class Invoice < ApplicationRecord
  has_and_belongs_to_many :products
end
# app/models/product.rb
class Product < ApplicationRecord
  has_and_belongs_to_many :invoices
end

Với cách này thì ta không phải tạo model cho bảng invoice_details.

Dù cả 2 cách đều yêu cầu bảng invoice_details tồn tại trong database nhưng nếu dùng has_and_belongs_to_many thì ta sẽ không thể validate khi tạo mỗi bản ghi của bảng invoice_details như cách dùng has_many :through do không có model.

Một lưu ý nhỏ các bạn cần để ý đó là tên của đối tượng được liên kết trong model. Các đối tượng bên n (bên nhiều) sẽ phải ở dạng số nhiều.

Trên đây là cách tạo ra association cho các model, bài sau mình sẽ trình bày cách sử dụng association.
Cảm ơn các bạn đã quan tâm theo dõi.

Tham khảo: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

0