Câu trả lời:
Nói rằng bạn có hai mô hình: User
và Group
.
Nếu bạn muốn có người dùng thuộc các nhóm, thì bạn có thể làm một cái gì đó như thế này:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
Điều gì nếu bạn muốn theo dõi siêu dữ liệu bổ sung xung quanh hiệp hội? Ví dụ: khi người dùng tham gia nhóm, hoặc có lẽ vai trò của người dùng trong nhóm là gì?
Đây là nơi bạn làm cho hiệp hội trở thành một đối tượng hạng nhất:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
Điều này giới thiệu một bảng mới và loại bỏ group_id
cột khỏi bảng của người dùng.
Vấn đề với mã này là bạn phải cập nhật mọi nơi bạn sử dụng lớp người dùng và thay đổi nó:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
Loại mã này hút, và nó làm cho việc giới thiệu những thay đổi như thế này đau đớn.
has_many :through
cung cấp cho bạn tốt nhất của cả hai thế giới:
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
Bây giờ bạn có thể coi nó như một bình thường has_many
, nhưng có được lợi ích của mô hình kết hợp khi bạn cần.
Lưu ý rằng bạn cũng có thể làm điều này với has_one
.
Chỉnh sửa: Giúp dễ dàng thêm người dùng vào nhóm
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user.groups << group
à? Hoặc là tất cả mọi thứ được xử lý bởi hiệp hội này?
Giả sử bạn có những mô hình này:
Car
Engine
Piston
Một chiếc xe has_one :engine
Một động cơ belongs_to :car
Một động cơ has_many :pistons
Pistonbelongs_to :engine
Một chiếc xe hơi has_many :pistons, through: :engine
Pistonhas_one :car, through: :engine
Về cơ bản, bạn đang ủy thác một mối quan hệ mô hình cho một mô hình khác, vì vậy thay vì phải gọi car.engine.pistons
, bạn chỉ có thể làmcar.pistons
has_many :through
và các has_and_belongs_to_many
mối quan hệ hoạt động thông qua một bảng tham gia , là một bảng trung gian thể hiện mối quan hệ giữa các bảng khác. Không giống như truy vấn THAM GIA, dữ liệu thực sự được lưu trữ trong một bảng.
Với has_and_belongs_to_many
, bạn không cần khóa chính và bạn truy cập vào các bản ghi thông qua quan hệ ActiveRecord thay vì thông qua mô hình ActiveRecord. Bạn thường sử dụng HABTM khi bạn muốn liên kết hai mô hình với mối quan hệ nhiều-nhiều.
Bạn sử dụng has_many :through
mối quan hệ khi bạn muốn tương tác với bảng tham gia dưới dạng mô hình Rails, hoàn thành với các khóa chính và khả năng thêm các cột tùy chỉnh vào dữ liệu đã tham gia. Cái sau đặc biệt quan trọng đối với dữ liệu có liên quan đến các hàng được nối, nhưng không thực sự thuộc về các mô hình liên quan - ví dụ: lưu trữ một giá trị được tính toán xuất phát từ các trường trong hàng được nối.
Trong Hướng dẫn về Hiệp hội hồ sơ hoạt động , khuyến nghị có nội dung:
Nguyên tắc đơn giản nhất là bạn nên thiết lập has_many: thông qua mối quan hệ nếu bạn cần làm việc với mô hình mối quan hệ như một thực thể độc lập. Nếu bạn không cần làm gì với mô hình mối quan hệ, có thể đơn giản hơn để thiết lập mối quan hệ has_and_belongs_to_many (mặc dù bạn sẽ cần nhớ để tạo bảng tham gia trong cơ sở dữ liệu).
Bạn nên sử dụng has_many: thông qua nếu bạn cần xác thực, gọi lại hoặc thuộc tính bổ sung trên mô hình tham gia.
user
mô hình để thêm nhóm. Một cái gì đó giống như chỉnh sửa tôi vừa thực hiện. Hi vọng điêu nay co ich.