Reputation: 495
To illustrate my question, i'll use the following association as listed on ruby guides for polymorphic associations:
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
Now in our :pictures
table, we will have 2 different columns, namely imageable_id
and imageable_type
.
The first thing that I am unclear of is, what exactly goes into imageable_type
? Is that something that the "rails magic" would automatically fill up when imageable_id
is declared?
Moving on to my next point (which will probably indirectly answer my uncertainty above), how do I assign either a Product
or Employee
to my Picture.new
form?
#create new picture form
#assume pre_created_array holds the :id for both Employee & Product
<%= form_for @picture do |f| %>
#relevant fields ontop
#choosing parent field is the one im unsure of
#this is what i assumed might be correct(?)
<%= f.select :imageable_id, options_for_select(pre_created_array) %>
<% end %>
Now does this form actually work? Is the building of the association something that has to be handled in the controller action instead? I am actually not very sure because usually in a regular association the parent can be declared before .save
, such as doing @post.employee = #find an employee
. So are we suppose to read the :imageable_id
?
#pictures controller
def create
@picture = Picture.new(picture_params)
#manipulate :imageable_id here???
if @picture.save
#blahblah other code
end
So i am actually quite unsure about this, whether it is supposed to be the form or controller handling the building of association. Which is why i'm bringing up this 2 "uncertainties".
Upvotes: 2
Views: 1028
Reputation: 1561
A polymorphic association is cool because it allows a single table to belong_to
multiple, as you know. So given a picture
, we don't have to know whether it belongs to an employee
or a product
, we can just call picture.imageable
and get the parent.
So if we don't have to know where the parent is, that must means Rails has to know. How does it know? imageable_type
! imageable_type
is the name of the class which it belongs to. In this case, either 'Employee'
or 'Product'
. That way, given the imageable_id
, it knows what table in which to search.
image.imageable
actually calls image.imageable_type.constantize.find(image.imageable_id)
Rails will do this "magic" for you if you simply assign objects instead of IDs. image.update(imageable: Product.first)
will assign both for you.
So in your form, you should be able work with a collection of objects and let Rails do the rest for you.
Upvotes: 2