Как отобразить все категории для отрасли, которая имеет sub_categories в grouped_collection_select в Rails

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня есть три модели. Отрасль, ProductCategory и ProductSubCategory. И связь между ними выглядит следующим образом:

 class Industry
  has_many :product_categories
end

class ProductCategory
  belongs_to :industry, optional: true
  has_many :product_sub_categories
end

class ProductSubCategory
  belongs_to :product_category
end
  

И я показываю select при использовании:

 <div class="form-group">
  <%= f.label :product_category %>
  <%= f.grouped_collection_select :product_category_id, Industry.all, 
    :product_categories, :name, :id, :name, { selected: 
     @product.product_category_id }, { class: "form-control form-
     control-alt", required: true } %>
 </div>
  

Но это работает не так, как я хочу. Он отображает все категории продуктов в каждой отрасли, но я просто хочу отображать только категории продуктов, у которых есть подкатегории.

Ответ №1:

Ваш вопрос состоит из двух частей:

1. Выбор категорий, у которых есть подкатегории.

Если у вас много данных — лучшим вариантом является использование кэша счетчика — добавьте product_sub_categories_count столбец в категории, установите counter_cache:true значение belongs_to и вызывайте ProductCategory.reset_counters(id, :product_sub_categories) для каждого идентификатора категории после миграции для заполнения.

И затем:

 scope :with_subcategories, ->{ where('product_sub_categories_count > 0') }
  

Другое простое решение для небольших наборов данных — вычислить это во время выполнения:

 scope :with_subcategories, ->{
  joins(:product_sub_categories).group(:id).select("product_categories.*, count(*) as product_sub_categories_count").
  having('product_sub_categories_count > 0')
}
  

2. Используя это в grouped_collection_select

Как только у нас появится область видимости — это станет проще:

 class Industry
  ...
  has_many :product_categories_with_subcategories, ->{ with_subcategories }
end

f.grouped_collection_select :product_category_id, Industry.all, 
  :product_categories_with_subcategories, :name, :id, :name,