我有一张大而扁平的桌子:
ID
PRODUCT_ID
ATTRIBUTE1
attribute2
attribute3
attribute4
以下是我希望用户访问产品的方式:
查看attribute1的唯一值列表
单击其中一个可获得attribute2的唯一值列表
单击其中一个可获得attribute3的唯一值列表
单击其中一个可获得attribute4的唯一值列表
点击其中一个会显示相关产品。
我已经编写了Rails大约4年了。我不能不考虑我目前解决这个问题的方法。
我有主要的作家。好像这么容易出问题。但我要么在我的控制器中使用4种不同的“步骤”方法对其进行编码,要么我尝试编写一种“搜索”方法,该方法试图判断您选择的最后一个级别以及您选择的所有先前值。
两人都是主要的YUCK,我一直在删除我的工作。
最优雅的方法是什么?
答案 0 :(得分:0)
这是一个可能是一个选项的解决方案。刚刚脱离我的头顶而没有经过测试(所以可能有一些更优雅的解决方案)。您可以在模型中使用链式范围:
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
上面的代码将为您提供每个属性的范围。如果将参数传递给作用域,则它将为您提供具有该属性值的产品。如果参数为nil,则范围将返回完整集(我认为;-)。您可以在控制器中使用2个变量(page_attribute和page_attribute_value)跟踪他们在会话中钻取的属性。然后你调用整个链来获取你的产品列表(如果你想在页面上使用它们)。接下来,您可以通过将产品集和属性名称传递给Product.available_attributes来获取属性值。请注意,此方法(Product.available_attributes)是一个完整的hack,对于大量数据集合效率低下,因此您可能希望将此另一个范围用于:select =&gt;“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
同样,我想警告你我没有测试这段代码,所以完全有可能某些语法不正确,但希望这会给你一个起点。 Holla如果您对我的(伪)代码有任何疑问。