Polymorphic Associations in Rails

Tram Ho

Anyone who works with Rails has probably heard of the Polymorphic Association – a great way to build relationships. In this article we will cover the Polymorphic Association issues

I. Concept

Polymorphic Associations is a type of Active Record Association that helps create links between a model and many other models through a single association. If not using polymorphic we will install it as shown below.

Normally, to find out the owner of a Picture, we look at the foreign_key column. Foreign_key is the id used to find a matching record in the table of the relevant model. However, Picture has two foreign keys: employee_id and product_id. The problem is that, when doing a search for a Picture owner, you’ll have to check both columns to find the correct foreign key, instead of one. What if a situation is encountered where both columns are valid? Also in this case there are only two tables, Employee and Product, if there are more tables than that, the amount of foreign_key that Picture needs to contain is very large. The Polymorphic Association solves this problem by lumping the function together into a single link. For example, we have 2 models, Employee and Product. For each Employee or Product we have many Pictures. If using has_many / belongs_to here, you must have two corresponding links between Employee and Pictures and Product and Pictures. Instead, we can use the Polymorphic Association to create a link to concurrently the Employee and Pictures models from Pictures. We come to the installation section to better understand this solution.

II. Setting

To let the database know, we first use Polymorphic Associations, we need to declare the foreign key column and the type column in the Picture table.

Inside :

  • imageable_id: foreign key
  • imageable_type: used to decide which model Picture is associated with (Employee or Product)

Or can be made simpler like:

By convention, Rails names a polymorphic link as the class name associated with the able extension. This is clearly shown in the relationship that it is a polymorphic class. But it is also possible to use any name for the polymorphic link, for example here use :imageable rather than :pictureable for the Picture class.

Next is the declaration of Polymorphic Association for Picture

By declaring Picture belongs_to imageable instead of Employee or Product, we have created a Polymorphic Association. Note: imageable is not a model or class in the system but just a representative name for the Polymorphic Association.

Next are 2 models Picture and Product

With the above declaration, we can understand that Employee and Product has_many Picture through polymorphic association imageable.

Then our relationships will look like:

Another special case, when applying polymorphic as comments. We consider the problem that a Room has many comments and a comment has many child comments. We will install the following:

III. Advantages and disadvantages

Links belongs to normal_to, we use foreign keys to refer to Polymorphic, we cannot have foreign keys, use type and id instead of foreign key.

In a normal belongs_to link, we use foreign keys to refer to the link. They actually have more than just a link. Foreign keys also prevent reference errors by requiring referenced objects to exist in the table. An error occurred when referring to a null object. But Polymorphic classes cannot have foreign keys, use type and id instead of foreign key. This means we lose the protection of foreign keys. If someone has direct access to the database, it is possible to create or update objects that refer to null objects.

For example, Comments are still created even if the linked Room doesn’t exist:

Strength

  • Easily scale data: data is distributed across a number of different tables to minimize tables.
  • Easily expand the number of models: more models can be easily combined with polymorphic classes.
  • DRY: create a class used for many other classes.

Weakness

  • Can not have a foreign key. The id column can refer to any associated model table, which slows down the query. It must be combined with type column.
  • If the table is large, it takes a lot of space to store the string values ​​for imageable type.
  • Data integrity is compromised.

IV. Single table inheritance or polymorphic associations?

A situation often occurs when some of these models need to have access to the functionality of a certain third party model.

  • Rails supports two ways we “cope” with these situations: single table inheritance and polymorphic associations.

Single table inheritance (STI)

STI is suitable for use when models share data or state. Many subclasses inherit from the same superclass.

A shop that distributes vehicles: Cars, Motorcycles, Bicycles. The manager wants to track information of each vehicle, including: color, price, purchased condition. This is a perfect scenario for using an STI, where the same data will be given to each class. Create a superclass Vehicle with color, price, and purchased properties. Then, the subclasses that inherit from it can get all of those properties.

So choose STI or Polymorphic Associations?

Based on four factors to consider when deciding whether to choose either of these methods is it right for your needs or not?

V. References

https://www.freecodecamp.org/news/single-table-inheritance-vs-polymorphic-associations-in-rails-af3a07a204f2/ https://guides.rubyonrails.org/association_basics.html#polymorphic-ass

Share the news now

Source : Viblo