Rails:动态选择要比较的属性

时间:2015-03-29 15:06:34

标签: ruby-on-rails ruby

我有一个我试图搜索的不同食物菜单的数据库。一般来说一切正常,但我认为与我现在所做的相比,编写代码必须有更聪明的方法。

每个菜单都有一组描述厨房类型的布尔属性(例如cuisine_thai,cuisine_italian等)。在我看来,我有一个下拉列表,允许用户选择他想要的食物类型,然后我传递参数并将其保存在我的搜索对象中。

@search.cuisine_type = params[:cuisine_type]

然后我继续检查不同的厨房类型,看看是否匹配。

#Filter for Thai cuisine
if(@search.cuisine_type == "cuisine_thai")
  @menus = @menus.select{ |menu| menu.cuisine_thai == true}
end
#Filter for French cuisine
if(@search.cuisine_type == "cuisine_italian")
  @menus = @menus.select{ |menu| menu.cuisine_italian == true}
end
#Filter for Peruvian cuisine
if(@search.cuisine_type == "cuisine_peruvian")
  @menus = @menus.select{ |menu| menu.cuisine_peruvian == true}
end

尽管我的工作方式很有效,但必须有更好的方法来做到这一点。我觉得@ search.cuisine_type中存储的值只能确定我在@menus上检查的属性。

非常感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

是的,你的直觉是正确的!

我假设@menus是一个数组是ActiveRecord Menu对象,cuisine_*属性对应于数据库列。在这种情况下,您可以使用ActiveRecord的attributes方法。

每个ActiveRecord对象都有attributes属性。文档(Rails 4.2.1)说:

  

<强>属性()   返回所有属性的哈希值,其名称为键,属性值为值。

要验证是这种情况,如果您查看给定菜单的attributes,您应该会看到一个包含以下内容的哈希:

{
  "cuisine_italian" => true,
  "cuisine_thai" => false,
  # etc.
}

此外,作为代码可读性的次要要点,这两个陈述实际上是相同的:

@menus = @menus.select { ... }
@menus.select! { ... }

因此,您的搜索可以重写为:

if @search.cuisine_type.present?
  @menus.select! { |m| m.attributes[@search.cuisine_type] }
end

答案 1 :(得分:0)

如果您在数据库中添加了“cuisine”列并将其设置为泰语,意大利语等,那会不会更好?

然后你只会检查某些食物是否与用户选择的一系列厨房相匹配。