Rails:根据多个参数显示产品

时间:2011-09-17 16:06:43

标签: ruby-on-rails ruby-on-rails-3 associations params

我正在学习rails并尝试设置一个产品库,其中的产品将根据三个元素显示:位置,类别和到期日期(产品可以有多个位置和类别,但只有一个到期日)。只要产品没有过期,产品就会显示,位置和类别选择将通过下拉菜单显示。

我开始写这个问题虽然难以合并我找到解决方案的位置和类别选择标准但是对于可以做得更好的任何帮助非常感谢。

我已经通过连接使用has_many来创建产品,位置和类别之间的连接。

以下是模型:

class Product < ActiveRecord::Base  
  has_many :categorizations  
  has_many :categories, :through => :categorizations  
  has_many :localizations  
  has_many :locations, :through => :localizations  
end  

class Categorization < ActiveRecord::Base
  belongs_to :product
  belongs_to :category
end  

class Category < ActiveRecord::Base
  has_many :categorizations
  has_many :products, :through => :categorizations
end  

class Localization < ActiveRecord::Base
  belongs_to :product
  belongs_to :location
end 

class Location < ActiveRecord::Base
  has_many :localizations
  has_many :products, :through => :localizations
end 

这是我的控制器。位置&amp;类别ID作为参数传递,产品的失效日期必须大于当前时间:

class LibraryController < ApplicationController
   def index
     @products = Product.find(:all, include => [ :locations, :categories ],
                              :conditions => ['expiry_date > ? AND locations.id = ? AND categories.id = ?',
                              Time.now, params[:location_id],params[:category_id]])
   end
end

因此,通过在URL中传递location_id和category_id参数,我可以通过两者的组合列出产品。

有没有更好的方法来实现我想要做的事情?

3 个答案:

答案 0 :(得分:1)

这也可以做你想要的:

@products = Product.find_all_by_category_id_and_location_id(params[:category_id], params[:location_id])

您还可以使用Product.where,这应该比查找更好。

有关详细信息,请参阅Google“动态查找器”。

答案 1 :(得分:0)

确定。不,我不认为在这种情况下有一种“更好”的方式。肯定有“不同”的方式来做你想做的事情,但从表面上看,你正在做的事情很好,并且没有尖叫出“这段代码很可怕!”或任何东西。

建议/风格的问题在这里很难回答,因为最终他们的答案是“在网上搜索其他人在你的情况下做了什么,并在你的解决方案似乎是传统/合乎逻辑的情况下自己评估/做出决定,或者通过研究有关该主题的相关书籍来回答这些问题。

几乎不可能回答这样的定性问题,因为:

  1. 有几种方法可以解决所有问题,其中很多都不是“正确”或“错误”
  2. 总有一些人们打破“规则”的边缘情况,在这种情况下,即使是非传统的解决方案也绝对是做某事的最佳方式
  3. 你是开发者,是构建东西的人。在某种程度上,你应该担任领导角色,并决定什么是最好的
  4. 我要求你定义“更好”的原因主要是因为#1 - 除非你给我们一个你想要达到的特定结果,你所得到的只是(a)充满意见的答案,而不是针对某个特定的目标或(b)只是采取不同的方式做某些可能会或可能不会帮助你的事情。因此,它们在实际上并不是很有用。

答案 2 :(得分:0)

您还可以使用“Product.where”(优先于rails 3.1中的find)改进您的解决方案,并将它们转换为Rails中的named_scopes并根据需要链接它们。

scope :not_expired, where('expiry_date > ?', Time.now)