Advantages and Disadvantages of Ruby on Rails Polymorphic Relationships

Advantages and disadvantages of Ruby on Rails polymorphic relationships

Advantages:

  • You can link anything to anything quite easily
  • Adaptable relationships help accommodating unforeseen circumstances
  • Very easy to implement relationships
  • Great for ad-hoc systems

Disadvantages:

  • Foreign keys not practical
  • Indexes include another dimension of complexity
  • Relationships between tables hard to identify when using STI
  • Database diagramming tools cannot interpret
  • Not always practical for join models
  • Strongly discouraged for systems where data integrity must be verified

I'm a big fan of using relationships of this sort for records that are attached to a large number of things as required, for example, a comment or annotation record which may apply to a wide variety of records.

It is not very well suited for situations where the relationship is exercised in a JOIN frequently. That is, the polymorphic association should not be in the middle of a relationship between records, but as something on the perimeter.

Are polymorphic associations necessary?

You could do that, but there will be disadvantages. Some that I can think of:

  1. Sparse table with many nulls

  2. No separation of concerns. Comments has to change whenever you add a commentable model

  3. Rails already supports polymorphic associations and makes it easy to use them. So why not?

What is the best practice to get the same behavior from multiple AR objects that are referred to polymorphically?

You could create a module called Linkable and create the behavior methods in that. Then you extend the module in the classes where you want to add those behaviors. This way you don't have to worry about inheriting from anything you can just mix-in the behavior.

This is the standard Ruby way of adding common functionality to multiple classes without inheriting. You would also, by convention, name your module using a verb based adjective instead of a verb; Linkable vs. Link.

For instance:

module Linkable
def link
puts "Look, I'm linked!"
end
end

class Product < ActiveRecord
extend Linkable
end

class Brand < ActiveRecord
extend Linkable
end

Of course your classes and the module will have actual functionality.

How can I handle this type of multi level forms in rails

What you're looking for are "nested forms" - they are really straight-forward to use.

in your Gemfile add:

gem "nested_form"

1) in your main_model, you'll include a call to accepts_nested_attributes_for :nested_model

class MainModel
accepts_nested_attributes_for :nested_model
end

2) in the view for your main_model instead of form_for() , you will call nested_form_for() at the top

= nested_form_for(@main_model) do |f|
...

Check the Rails page for that method, it has interesting options, e.g. :reject_if , :allow_destroy, ...

3) in the view for the main_model, when you want to show a sub-form for the nested model, you will do

= f.fields_for :nested_model   # replace with your other model name

it will then just use the _form partial for the nested_model and embed it in the view for the main_model

works like a charm!

Check these RailsCast.com episodes, which cover Nested Forms in depth:

http://railscasts.com/episodes/196-nested-model-form-part-1

http://railscasts.com/episodes/197-nested-model-form-part-2

hope this helps



Related Topics



Leave a reply



Submit