Polymorphic association

2020-05-27 11:07发布

问题:

If you have polymorphic belongs_to associations then references will add both of the columns required:

create_table :products do |t|
  t.references :attachment, :polymorphic => {:default => 'Photo'}
end

will add an attachment_id column and a string attachment_type column with a default value of ‘Photo’.

What, exactly, does this mean?

回答1:

Basically, polymorphic association by definition adds ability to create associations with many other Rails ActiveRecord Models.

Both Columns are there for Rails to know which Model the association is referring to, you have the attachment_type column (ie String) (default value is "Photo",table-name: photos in the db), and the attachment_id is sort of like a foreign key to that particular Model/table (ie Photo).

Usually this provides you flexibility to associate one Model to many others.



回答2:

Here is the documentation on the references method: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#M001938

The code of the references method is as follows:

497:       def references(*args)
498:         options = args.extract_options!
499:         polymorphic = options.delete(:polymorphic)
500:         args.each do |col|
501:           column("#{col}_id", :integer, options)
502:           column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
503:         end
504:       end

As you can see. It adds both a [col]_id and [col]_type column to the table.

It's the same as saying:

create_table :products do |t|
  t.integer :attachment_id
  t.string  :attachment_type, :default => 'Photo'
end

Polymorphic associations are used to connect one kind of objects to multiple kinds of other objects.

A good example might be an application that supports tags, where tags can be connected to both Products and Categories.

In your example, it looks like Products could be attached to multiple kinds of objects, where the default kind of object is a Photo. (attachment_type would be "Photo", and attachment_id would be an id of a row in the 'photos' table)



回答3:

polymorphic means that it can belong to different objects (or, different records in different tables). The way it determines this is based on the type and id fields. If your association was not polymorphic it would only have an _id field.