Jane Jane - 7 months ago 14
Ruby Question

Creating an ActiveRecord Relation of parent instances with specific child instances

I made categories using this comment as a guide. I set categories as a resource in my routes, and used this to query the specific

Product
instances:

class CategoriesController < ApplicationController
def show
@category = Category.find(params[:id])
@products = []

products = Product.all

products.each do |product|
if product.categories.include?(@category)
@products << product
end
end
end
end


I then iterate over
@products
in my view. This has become a problem because I want
categories/show
to share a view with
products/index
to be more DRY.
products/index
just uses
<%= render @products %>
, and I can't pass
render
an array.

How can I query products with specific categories?

Pseudo-ish code of what I had in mind:

class CategoriesController < ApplicationController
def show
@category = Category.find(params[:id])
@products = Product.where(categories.include?(@category))
end
end


Category setup from comment:

class Category < ActiveRecord::Base
acts_as_tree order: :name
has_many :categoricals
validates :name, uniqueness: { case_sensitive: false }, presence: true
end

class Categorical < ActiveRecord::Base
belongs_to :category
belongs_to :categorizable, polymorphic: true

validates_presence_of :category, :categorizable
end

module Categorizable
extend ActiveSupport::Concern

included do
has_many :categoricals, as: :categorizable
has_many :categories, through: :categoricals
end

def add_to_category(category)
self.categoricals.create(category: category)
end

def remove_from_category(category)
self.categoricals.find_by(category: category).maybe.destroy
end

module ClassMethods
end
end

class Product < ActiveRecord::Base
include Categorizable
end

p = Product.find(1000) # returns a product, Ferrari
c = Category.find_by(name: 'car') # returns the category car

p.add_to_category(c) # associate each other
p.categories # will return all the categories the product belongs to

Answer

I think this is your main question:

How can I query products with specific categories?

Product.includes(:categories).where(categories: {id: params[:id]}).references(:categories)

Check out this link for more info on preloading associations: http://blog.arkency.com/2013/12/rails4-preloading/