+1

STI and Polymorphic Associations

STI và Polymorphic Associations là những cách thông thường áp dụng để kết nối giữa hai bảng dựa trên một điều kiện nào đó. Giả sử chúng ta có một bảng trong database được gọi là comment, và chúng ta có thể có comment cho nhiều loại ví dụ như comments cho một video, hay một status hay một bức ảnh đại diện,.. Vì vậy khi tuân thủ theo DRY khi thiết kế database, chúng ta có thể nghĩ đến quan hệ giữa bảng comment với các video, status, hay ảnh đại diện ở trên. Ở phiến diện database, chúng ta nên có hai trường trong bảng comment, một trường định nghĩa kiểu của comment(type) để phân biệt comment cho video hay comment status, một trường sẽ lưu id của video hay status mà nó trỏ tới. Còn đối với trong rails, có 2 cách để định nghĩa kiểu quan hệ trên giữa các model trên:

STI - Single Table Inheritance

Đối với STI, bạn sẽ tạo một bảng comment với model tương ứng là class Comment. Sẽ có 2 class thêm vào tương ứng là VideoCommentStatusComment được thừa kế từ class Comment. Nếu chúng ta nhìn vào bảng comment, chúng ta sẽ thấy rằng mỗi một class sẽ tự động lưu lại thông tin trường type"video""status". Còn một trường source_id sẽ lưu id của video hoặc status tương ứng với nó. Định nghĩa của các class sẽ như sau:

class Comment < ActiveRecord::Base
end
class VideoComment < Comment
belongs_to :video, :foreign_key => "source_id"
end
class StatusComment < Comment
belongs_to :status, :foreign_key => "source_id"
end

Polymorphic Association

Kể từ rails 1.1, chúng ta có thể tạo kiểu quan hệ trên theo polymorphic association định nghĩa. Với polymorphic association, trong bảng comment chúng ta sẽ có 2 trường là commentable_typecommentable_id thay vì type vào source_id như STI ở trên. Trường commentable_type sẽ lưu tên class mà comment đó quan hệ tới là "Video" hay "Status", còn commentable_id sẽ lưu id của video/status tương ứng với nó. Định nghĩa của các class sẽ như sau:

class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
class Video < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Status < ActiveRecord::Base
has_many :comments, :as => :commentable
end

REFS

STI vs. Polymorphic association


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.