12/08/2018, 15:43

Self join trong ruby

mối quan hệ SELF-JOIN (tự vấn) ONE-TO-MANY: một model có thể được tái sử dụng với chính nó, giả sử nhân viên và quản lý đều là user nên chỉ cần dùng self-join trong bảng user là đủ, cách sử dụng: trong model user tạo thêm: has_many :nhanvien, class_name: User.name, foreign_key: ...

mối quan hệ SELF-JOIN (tự vấn) ONE-TO-MANY:

một model có thể được tái sử dụng với chính nó, giả sử nhân viên và quản lý đều là user nên chỉ cần dùng self-join trong bảng user là đủ, cách sử dụng:

  • trong model user tạo thêm:
has_many :nhanvien, class_name: User.name, foreign_key: :manager_id
belongs_to :manager, class_name: User.name, required: false
  • chú ý: tạo thêm cột manager_id cho model User (có thể thêm t.references :manager trong schema.rb), required: false - để sửa lỗi trong rails 5 (khi belongs_to mặc định là required).

mối quan hệ SELF-JOIN (MANY TO MANY):"FOLLOWING"

một model có thể có liên kết many-to-many ngay ở trong nó, ví dụ 1 user có thể following nhiều người khác và có thể được nhiều người khác follow mình.

  • Tạo một model trung gian lưu trữ quan hệ. gọi đó là model Follow gồm follower_id (người theo dõi), followed_id (người bị theo dõi).

  • thiết lập mối quan hệ trong model Follow:

belongs_to :follower, class_name: User.name
belongs_to :followed, class_name: User.name
  • thiết lập mối quan hệ trong model
has_many :active_follows, class_name: Follow.name,
foreign_key: :follower_id
has_many :following, through: :active_follow,
source: :followed

has_many :passive_follows, class_name: Follow.name,
foreign_key: :followed_id
has_many :follower, through: :active_follow

=> từ model chính ta phải mở thêm 2 đường kết nối tới bảng phụ, một trỏ tới follower_id để tạo kết nối chủ động, một user đi follow 1 user khác, một trỏ tới followed_id để tạo liên kết thụ động, được người khác follow.

  • để thao tác dễ dàng hơn thì ta dùng thêm has_many through để viết lại 2 thao tác trên.
  • để tạo một liên kết follow từ 2 liên kêt has_many tạo thêm ta dùng các cách sau (dùng cho has_many through):
user.following << other_user : tạo 1 liên kết mới
user.following.delete other_user : xóa liên kết
user.following.include? other_user : kiêm tra xem có liên kết user following other_user (true || false)
0