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:
Sparse table with many nulls
No separation of concerns. Comments has to change whenever you add a commentable model
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
Firebase Token Error, "The Custom Token Corresponds to a Different Audience."
Turning a Hash of Arrays into an Array of Hashes in Ruby
Time_Ago_In_Words and Localize
Using Named Captures with Regex Match in Ruby's Case...When
Connecting Using Https to a Server with a Certificate Signed by a Ca I Created
Jekyll: How to Use Custom Plugins with Github Pages
Do You Know an Alternative Ctags Generator for Ruby
Ruby/Ror: Calling Original Method via Super()
Testing a Concern/Module That Uses Activerecord
Multiple Blogs in Single Jekyll Website
Refactoring a Large Routes.Rb File in Rails 4
After Installing Ruby Gems, Running the New Gem Returns "Could Not Find" Errors
Are Ruby 1.9 Regular Expressions Equally Powerful to a Context Free Grammar