Reputation: 288
My models include Stores which have a number of Images. (There are other models that can have Images, too.) Out of all Images that are assigned to a Store, I would like to set a "main image" which will be presented first on the Store's page. Other than that the main image should be treated in the same way as all others.
What is the best practice?
The models basically look like this:
class Store < ActiveRecord::Base
has_many :images, as: :imageable, dependent: :destroy
end
and
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
Upvotes: 1
Views: 321
Reputation: 101811
Adding a foreign key reference to the stores table is not actually a bad idea.
Since polymorphic relationships are resolved in the software layer and not in the RBDMS there is nothing in the DB which maintains the referential integrity. The DB will for example happily let you delete the primary image for a store.
First lets generate a migration:
class AddPrimaryImageToStores < ActiveRecord::Migration[5.0]
def change
# we need to setup the foreign_key manually
add_reference :stores, :primary_image, foreign_key: false
add_foreign_key :stores, :images, column: 'primary_image_id'
end
end
Then lets setup the relation:
class Store < ActiveRecord::Base
has_many :images, as: :imageable, dependent: :destroy
belongs_to :primary_image, class_name: 'Image'
end
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
# one to one.
has_one :primary_store, class_name: 'Store'
foreign_key: 'primary_image_id'
end
The direct relationship with a foreign key allows you to perform highly effective joins which is especially important if you are displaying stores and the primary image together.
Upvotes: 2
Reputation: 2197
You can add some boolean field to your image model to define if image is main, and add scope to your model to get this main image by that new boolean field
Upvotes: 0