Sha256: b0829a2d39cc23a5fc21622ad6ffeeffc2862285e6bb14925a882ab6c8b86e4c

Contents?: true

Size: 1.98 KB

Versions: 25

Compression:

Stored size: 1.98 KB

Contents

# frozen_string_literal: true

module Decidim
  # Categories serve as a taxonomy for components to use for while in the
  # context of a participatory process.
  class Category < ApplicationRecord
    include Decidim::TranslatableResource

    translatable_fields :name, :description

    belongs_to :participatory_space, foreign_key: "decidim_participatory_space_id", foreign_type: "decidim_participatory_space_type", polymorphic: true
    has_many :subcategories, foreign_key: "parent_id", class_name: "Decidim::Category", dependent: :destroy, inverse_of: :parent
    belongs_to :parent, class_name: "Decidim::Category", inverse_of: :subcategories, optional: true
    has_many :categorizations, foreign_key: "decidim_category_id", class_name: "Decidim::Categorization", dependent: :destroy

    default_scope { order(arel_table[:parent_id].asc, arel_table[:weight].asc) }

    validate :forbid_deep_nesting
    before_validation :subcategories_have_same_participatory_space

    # Scope to return only the first-class categories, that is, those that are
    # not subcategories.
    #
    # Returns an ActiveRecord::Relation.
    def self.first_class
      where(parent_id: nil)
    end

    def descendants
      @descendants ||= Category.where(parent_id: id)
    end

    def translated_name
      Decidim::CategoryPresenter.new(self).translated_name
    end

    def unused?
      categorizations.empty?
    end

    # Allow ransacker to search for a key in a hstore column (`name`.`en`)
    ransacker :name do |parent|
      Arel::Nodes::InfixOperation.new("->>", parent.table[:name], Arel::Nodes.build_quoted(I18n.locale.to_s))
    end

    private

    # This is done since we only allow one level of subcategories.
    def forbid_deep_nesting
      return unless parent
      return if parent.parent.blank?

      errors.add(:parent_id, :nesting_too_deep)
    end

    def subcategories_have_same_participatory_space
      return unless parent

      self.participatory_space = parent.participatory_space
    end
  end
end

Version data entries

25 entries across 25 versions & 1 rubygems

Version Path
decidim-core-0.24.2 app/models/decidim/category.rb
decidim-core-0.24.1 app/models/decidim/category.rb
decidim-core-0.24.0 app/models/decidim/category.rb
decidim-core-0.24.0.rc2 app/models/decidim/category.rb
decidim-core-0.24.0.rc1 app/models/decidim/category.rb