Вот решение, которое может быть вариантом. Просто с макушки головы и не проверял (так что, наверное, есть более элегантное решение). Вы можете использовать цепочки прицелов в вашей модели:
class Product < ActiveRecord::Base
scope :with_capacity, lambda { |*args| args.first.nil? ? nil : where(:capacity=>args.first) }
scope :with_weight, lambda { |*args| args.first.nil? ? nil : where(:weight=>args.first) }
scope :with_color, lambda { |*args| args.first.nil? ? nil : where(:color=>args.first) }
scope :with_manufacturer, lambda { |*args| args.first.nil? ? nil : where(:manufacturer=>args.first) }
self.available_attributes(products,attribute)
products.collect{|product| product.send(attribute)}.uniq
end
end
Приведенный выше код даст вам область действия для каждого атрибута. Если вы передадите параметр в область, то он даст вам продукты с этим значением атрибута. Если аргумент равен нулю, то область действия вернет полный набор (я думаю ;-). Вы можете отслеживать атрибуты, которые они детализируют в сеансе, используя 2 переменные (page_attribute и page_attribute_value) в вашем контроллере. Затем вы звоните по всей цепочке, чтобы получить список продуктов (если вы хотите использовать их на странице). Затем вы можете получить значения атрибутов, передав набор продуктов и имя атрибута в Product.available_attributes. Обратите внимание, что этот метод (Product.available_attributes) является полным хаком и будет неэффективным для большого набора данных, поэтому вы можете захотеть сделать эту другую область и использовать: select => "DISTINCT (your_attribute)" или что-то более эффективное для базы данных вместо того, чтобы повторять весь набор продуктов, как я делал в методе взлома.
class ProductsController < ApplicationController
def show
session[params[:page_attribute].to_sym] = params[:page_attribute_value]
@products = Product.all.with_capacity(session[:capacity]).with_weight(session[:weight]).with_color(session[:color]).with_manufacturer(session[:manufacturer])
@attr_values = Product.available_attributes(@products,params[:page_attribute])
end
end
Опять же, я хочу предупредить вас, что я не тестировал этот код, поэтому вполне возможно, что какой-то синтаксис неверен, но, надеюсь, это даст вам отправную точку. Привет, если у вас есть какие-либо вопросы по поводу моего (псевдо) кода.