Reputation: 233
In my rails app, I am trying to select all of the child models ( ‘pdfs’ ‘videos’ ‘infographics’ ) which have a reference to a parent model (‘category’). These three child models can belong to only one of three parent models (this is enforced using an Exclusive arc validation in the child models). So they have a one in three chance of belonging my parent model (‘category’).
Is there a way of selecting all of the children models ( ‘pdfs’ ‘videos’ ‘infographics’ ), which are attached to my specific parent model (‘category’)? If i am able to do this, is it possible to sort each of these instances of the children models by the date they were created? And finally, would I be able to have this ordered list of children instances as an array, so that I can iterate over it in the view?
Thank you for your help! Model set up below.
The parent model:
class Category < ApplicationRecord
belongs_to :navbar_base_folder
has_many :sub_categories, dependent: :destroy
has_many :infographics, dependent: :destroy
has_many :videos, dependent: :destroy
has_many :pdfs, dependent: :destroy
end
The three children:
class Pdf < ApplicationRecord
belongs_to :sub_category, optional: true
belongs_to :category, optional: true
belongs_to :secret_category, optional: true
belongs_to :secret_sub_category, optional: true
end
class Video < ApplicationRecord
belongs_to :sub_category, optional: true
belongs_to :category, optional: true
belongs_to :secret_category, optional: true
belongs_to :secret_sub_category, optional: true
end
class Infographic < ApplicationRecord
belongs_to :sub_category, optional: true
belongs_to :category, optional: true
belongs_to :secret_category, optional: true
belongs_to :secret_sub_category, optional: true
end
Upvotes: 0
Views: 464
Reputation: 186
This is a perfect candidate for single table inheritance (STI).
class Category < ApplicationRecord
has_many :contents, dependent: :destroy
has_many :infographics
has_many :pdfs
has_many :videos
end
# db/migrate/create_content.rb
# Create a migration for Content
create_table :content do |t|
# .... add your attributes here ...
t.string :type, index: true
end
end
# app/models/content.rb
class Content < ApplicationRecord
belongs_to :category
# `has_many ... optional: true` is not invalid, but you should aim to
# keep your associations & validations separate. Instead put this as a
# validation:
validates :category, presence: true
end
# app/models/pdf.rb
class Pdf < Content; end
# app/models/infographic.rb
class Infographic; end
# app/models/video.rb
class Video < Content; end
Then find all content:
@category = Category.first
@contents = @category.contents.order(date: :desc)
Hope that helps :)
P.S: Your Category
should be refactored to a parent/child pattern if possible:
class Category < ApplicationRecord
# app/models/category.rb
# Your `Category` table should be using a `parent_id` column, not creating a "sub_category" model.
belongs_to :parent_category, foreign_key: :parent_id, class_name: 'Category'
has_many :sub_categories, foreign_key: :parent_id, class_name: 'Category'
attribute :is_secret, Boolean
end
Upvotes: 1