Skip to content

Instantly share code, notes, and snippets.

@at-longhoang
Created March 17, 2016 09:48
Show Gist options
  • Save at-longhoang/b3c83aab52bcc675a8d3 to your computer and use it in GitHub Desktop.
Save at-longhoang/b3c83aab52bcc675a8d3 to your computer and use it in GitHub Desktop.
Quan hệ đa hình trong rails
Giả sử có có 2 model Course and Lab. Tiết học và Lab đều cần trợ giảng.
Vì vậy nếu sử dụng has_many/belongs_to ở đây. sẽ phải cần
2 model tương tự nhau giữa TA of course và TA of Lab. Thay vì có
2 model khác nhau.bạn có thể chỉ cần có 1. Bạn có thể liên kết model
này với mỗi bên bằng cách sữ dụng quan hệ đa hình.
rails g model TeachingAssistant name:string ta_duty_id:integer ta_duty_type:string
ta_duty_id là khóa ngoại. ta_duty_type để chỉ ra rằng TA model là
model sẽ được liên kết.
class CreateTeachingAssistants < ActiveRecord::Migration
def change
create_table :teaching_assistants do |t|
t.string :name
t.integer :ta_duty_id
t.string :ta_duty_type
t.timestamps
end
end
end
rake db:migrate
class TeachingAssistant < ActiveRecord::Base
belongs_to :ta_duty, polymorphic: true
end
Bằng cách belongs_to ta_duty thay vì thuộc về model khác. chúng
ta đã khai báo đa hình.
Chú ý là tên ta_duty phải đặc trưng. ko được trùng model/class nào khác
class Course < ActiveRecord::Base
has_many :teaching_assistants, as: :ta_duty
end
class Lab < ActiveRecord::Base
has_many :teaching_assistants, as: :ta_duty
end
Code ở trên chỉ ra rằng Course và Lab có nhiều TA thông qua
mối quan hệ đa hình ta_duty.
Hình vào hình minh họa để xem cái ta đang set up.
https://launchschool.com/blog/images/2014-10-16-understanding-polymorphic-associations-in-rails/polymorphic.png
Testing
Loading development environment (Rails 4.1.1)
2.0.0-p247 :001 > ta = TeachingAssistant.create(name: 'ta_name')
2.0.0-p247 :002 > c = Course.create(name: 'course_name')
2.0.0-p247 :003 > ta.update_attribute(:ta_duty, c)
=> true
2.0.0-p247 :004 > Course.last.teaching_assistants.last.name
=> "ta_name"
2.0.0-p247 :005 >
STI vs Polymorphic Association
Cái này củ chuối thật. Không chơi
class TeachingAssistant < ActiveRecord::Base
class CourseTa < TeachingAssistant
class LabTa < TeachingAssistant
Kết hợp quan hệ nhiều nhiều (has_many :through) và đa hình.
Hơi bối rối tý ở lần đầu ở đây.
Thêm bảng Professor.
Đương nhiên giáo sư thì có nhiều trợ giảng.
class Professor < ActiveRecord::Base
has_many :teaching_assistants
has_many :course_tas, through: :teaching_assistants, source: :ta_duty, source_type: 'Course'
has_many :lab_tas, through: :teaching_assistants, source: :ta_duty, source_type: 'Lab'
end
Ở model trợ giảng. Trợ giảng thì thuộc về giáo sư.
class TeachingAssistant < ActiveRecord::Base
belongs_to :professors
belongs_to :ta_duty, polymorphic: true
end
Có thể test bằng rails c. Professor.first.course_tas
:source
The :source option specifies the source association name for a has_one :through association.
:source_type
The :source_type option specifies the source association type for a has_one :through association that proceeds through a polymorphic association.
inverse_of không sử dụng được trong đa hình.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment