activerecord - Rails 5: STI With Has Many Through Association -
i have searched extensively solution situation, can't find anything.
in application have person
model only stores data people:
class person < applicationrecord end
then have trial
model. trials can have many people using has-many-through association. additionally, in context of trial, person can defendant or plaintiff. achieve this, set models this:
class trial < applicationrecord has_many :trial_people has_many :plaintiffs, class_name: 'plaintiff', through: :trial_people, source: :person has_many :defendants, class_name: 'defendant', through: :trial_people, source: :person end class trialperson < applicationrecord belongs_to :trial belongs_to :person end class plaintiff < person end class defendant < person end
i using select2 jquery plugin add in defendants , plaintiffs each trial in view. obtaining ids in strong parameters:
params.require(:trial).permit(:title, :description, :start_date, :plaintiff_ids => [], :defendant_ids => [])
so can achieve following:
trial.defendants trial.plaintiffs
the problem not have way of distinguishing between classes inside trial_people
table. thinking on adding type
column table (sti), not know how automatically add type each defendant or plaintiff when saving trial object.
would appreciate insight on how achieve this, using sti or not.
one way can go without changing associations or schema use before_create
callback.
assuming you've added person_type
string column trial_people
class trialperson < applicationrecord belongs_to :trial belongs_to :person before_create :set_person_type private def set_person_type self.person_type = person.type end end
another way approach remove person
association , replace polymorphic triable
association. achieves same end result it's built activerecord api , doesn't require callbacks or custom logic.
# migration class addtriablereferencetotrialpeople < activerecord::migration def remove_reference :trial_people, :person, index: true add_reference :trial_people, :triable, polymorphic: true end def down add_reference :trial_people, :person, index: true remove_reference :trial_people, :triable, polymorphic: true end end # models class trialperson < applicationrecord belongs_to :trial belongs_to :triable, polymorphic: true end class person < applicationrecord has_many :trial_people, as: :triable end class trial < applicationrecord has_many :trial_people has_many :defendants, source: :triable, source_type: 'defendant', through: :trial_people has_many :plaintiffs, source: :triable, source_type: 'plaintiff', through: :trial_people end class plaintiff < person end class defendant < person end
this gives triable_type
, triable_id
columns on trial_people
table set automatically when add collections
trial = trial.create trial.defendants << defendant.first trial.trial_people.first # => #<trialperson id: 1, trial_id: 1, triable_type: "defendant", triable_id: 1, ... >
Comments
Post a Comment