Reputation: 412
I have model named Slider
class Slider < ActiveRecord::Base
end
and HomeBannerSlider
which has single table inheritance relation with slider
class HomeBannerSlider < Slider
has_many :images, as: :imageable
accepts_nested_attributes_for :images, reject_if: :all_blank, allow_destroy: true
end
and Image
model as given
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
has_attached_file :image
end
My problem is whenever I save HomeBannerSlider
with following command
@admin_home_banner_slider = HomeBannerSlider.new(admin_home_banner_slider_params)
@admin_home_banner_slider.save
It saves the imageable_type
in Image
model as Slider
@admin_home_banner_slider.images
<Image:0x007f5e6ef7af20
id: nil,
imageable_id: nil,
imageable_type: "Slider",
title: "2",
description: "2",
link_button: nil,
link_button_title: nil,
owner: nil,
publish: nil,
priority: nil,
created_at: nil,
updated_at: nil,
image_file_name: nil,
image_content_type: nil,
image_file_size: nil,
image_updated_at: nil>]
but i want it to store imageable_type
as HomeBannerSlider
Upvotes: 3
Views: 520
Reputation: 49890
From the activerecord documentation - http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations - "Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association".
So rails specifically wants the base type stored there, it will still load the correct type if you access my_image.imageable since it uses the type from the Slider table when creating that object and ids are unique for the whole Slider table, not just in each type in the table.
That all being said, there is a gem that adds the behavior you want to rails - https://github.com/appfolio/store_base_sti_class
Upvotes: 2
Reputation: 454
You can override the imageable_type in your model as
def imageable_type=(imageType)
super(imageType.classify.constantize.base_class.to_s)
end
Upvotes: 1
Reputation: 1923
Try to add this in your Image
model:
before_validation :set_type
def set_type
self.imageable_type = imageable.class.name
end
Upvotes: 1