Created
June 3, 2025 17:11
-
-
Save ismarsantos/629f053035a696ed203c308a0fd1e92a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1. Migration para criar a tabela associativa polimórfica | |
# db/migrate/xxxx_create_categorizations.rb | |
class CreateCategorizations < ActiveRecord::Migration[7.2] | |
def change | |
create_table :categorizations do |t| | |
t.references :category, null: false, foreign_key: true | |
t.references :categorizable, polymorphic: true, null: false | |
t.timestamps | |
end | |
add_index :categorizations, [:categorizable_type, :categorizable_id] | |
add_index :categorizations, [:category_id, :categorizable_type, :categorizable_id], unique: true, name: 'index_categorizations_unique' | |
end | |
end | |
class Category < ApplicationRecord | |
has_many :categorizations, dependent: :destroy | |
has_many :amenities, through: :categorizations, source: :categorizable, source_type: 'Amenity' | |
has_many :plans, through: :categorizations, source: :categorizable, source_type: 'Plan' | |
validates :name, presence: true, uniqueness: true | |
end | |
# 3. Model Categorization (tabela associativa) | |
# app/models/categorization.rb | |
class Categorization < ApplicationRecord | |
belongs_to :category | |
belongs_to :categorizable, polymorphic: true | |
validates :category_id, uniqueness: { scope: [:categorizable_type, :categorizable_id] } | |
end | |
# 4. Model Amenity | |
# app/models/amenity.rb | |
class Amenity < ApplicationRecord | |
has_many :categorizations, as: :categorizable, dependent: :destroy | |
has_many :categories, through: :categorizations | |
validates :name, presence: true | |
end | |
# 5. Model Plan | |
# app/models/Plan.rb | |
class Plan < ApplicationRecord | |
has_many :categorizations, as: :categorizable, dependent: :destroy | |
has_many :categories, through: :categorizations | |
validates :name, presence: true | |
end | |
# 6. Exemplos de uso no console/controller | |
# Criar categorias | |
core = Category.create!(name: 'Core Amenities') | |
basic = Category.create!(name: 'Spa') | |
outdoor = Category.create!(name: 'Outdoor') | |
# Criar amenities e plans | |
pool = Amenity.create!(name: 'Swimming Pool') | |
gym = Amenity.create!(name: 'Gym') | |
studio = Plan.create!(name: 'Studio') | |
loft = Plan.create!(name: 'Loft') | |
# Associar categorias | |
pool.categories << [core, outdoor] | |
gym.categories << core | |
studio.categories << basic | |
loft.categories << core | |
# Consultas | |
core.amenities # => [pool, gym] | |
core.plans # => [loft] | |
pool.categories # => [core, outdoor] | |
# Método para buscar categorias por tipo | |
def categories_for_type(type) | |
case type.downcase | |
when 'amenity' | |
Category.joins(:categorizations) | |
.where(categorizations: { categorizable_type: 'Amenity' }) | |
.distinct | |
when 'Plan' | |
Category.joins(:categorizations) | |
.where(categorizations: { categorizable_type: 'Plan' }) | |
.distinct | |
end | |
end | |
# 7. Concern para facilitar reutilização (opcional) | |
# app/models/concerns/categorizable.rb | |
module Categorizable | |
extend ActiveSupport::Concern | |
included do | |
has_many :categorizations, as: :categorizable, dependent: :destroy | |
has_many :categories, through: :categorizations | |
end | |
def add_category(category) | |
categories << category unless categories.include?(category) | |
end | |
def remove_category(category) | |
categories.delete(category) | |
end | |
def categorized_as?(category_name) | |
categories.exists?(name: category_name) | |
end | |
end | |
# Para usar o concern, substitua has_many nos models por: | |
# include Categorizable |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment