Hello everyone, Today I would like to introduce to you a pretty good solution to build model relationships in Ruby on Rails programming.
For example
Suppose we have a problem with table relations as follows: Table Product
has many Member
. And a Group
also has many Member
.
The usual way I think most of us will be to establish a belongs_to/has_many
relationship for the Product has_many Member
and Group has_many Member
tables.
After that, Member
and will have to generate 2 foreign keys for Product
and Group
.
We can see that if applying the above solution, 2 foreign keys go to Member
=> okay.
And if there are many such relationships in an application with Member
. For example Team, Country...
the number of sub-keys must be generated is quite good. This affects the “mentality and passion of programming” of programmers in a negative way
Is there a way to establish relationships in Ruby on Rails without having to generate so many subkeys like this?
And the right dharma to this issue is the Polymorphic Associations
Concept of Polymorphic Associations in Ruby on Rails
Basically, you can understand the following: Active Record Associations is one of the most important features of Rails. Polymorphic association is part of these associations.
They are born to resolve NN relationship problems in Rails with the statement: “with polymorphic associations, one model can belong to more than one model, on a single association.”
Go back to the original example. Let’s take a look at how things look like when using the Polymorphic Associations!
Create model common association
1 2 | rails g model MemberAssistant name:string ta_duty_id:integer ta_duty_type:string |
In which we have ta_duty_id
as the id of the corresponding Product
or Group
and ta_duty_type
will tell us which model
is associated with MemberAssistant
Migrate Data: rails db:migrate
Set up the Assistant model
/app/models/member_assistant.rb
1 2 3 4 | class MemberAssistant < ActiveRecord::Base belongs_to :ta_duty, polymorphic: true end |
By making MemberAssistant
belong to ta_duty
instead of any other model
, we have declared polymorphic association
with the keyword polymorphic: true
. Note that we don’t have any model /class
ta_duty in our application, ta_duty
only interested in polymorphic association
.
/app/models/product.rb
1 2 3 4 | class Product < ActiveRecord::Base has_many :member_assistants, as: :ta_duty end |
Same for Group
We see that the Product
and Group
have many MemberAssistant
through the polymorphic association ta_duty
. Thus, we can see that the MemberAssistant
model is linked to the Product
and Group
models through only two fields, ta_duty_id
and ta_duty_type
.
We’ll use the rails console for a bit of testing!
1 2 3 4 5 6 7 | 2.0.0-p247 :001 > ma = MemberAssistant.create(name: 'M name') 2.0.0-p247 :002 > p = Product.create(name: 'P name') 2.0.0-p247 :003 > ma.update_attribute(:ta_duty, p) => true 2.0.0-p247 :004 > Product.last.member_assistants.last.name => "M name" |
Thus, Product has_many MemberAssistant
relationship has been formed.
This relationship is also the relationship of Group, Team, Country
with Member.
And what I want to say here is that we only need 2 fields in the MemberAssistant
table.
Conclude
Taken together, there are 2 main purposes of the use of Polymorphic Associations are:
- Reduce the amount of foreign_key
- For a multi-role problem, there will be an intermediate table. It helps clarify the role of tables to intermediate tables.
Above is a technique that I think is quite good. And I have shared with you, hope you will apply well.
Thanks for the reference!