我已经编辑了我的第一个代码,现在由于@FunTimeFreddie它更好更清洁,但问题还没有得到妥善解决。我会尽快回答正确的答案。
在搜索表单中,我需要过滤所有菜单项: 1.每个类别 2.按类别搜索“查询” 3.每分钟价格&& ||最高价格 ...等等,包含所有可能的组合
我设法使用“查询”,min_price和max_price在所有菜单项中搜索 - 搜索表单中的所有可能组合。我无法获得所选类别的结果列表,我做错了什么?
这是我的模特(编辑):
class Menuitem < ActiveRecord::Base
belongs_to :menu_category
include Filterable
scope :newest_first, lambda { order('menuitems.created_at DESC') }
scope :last_one, lambda { order('menuitems.created_at ASC').last }
scope :search_keyword, lambda { |query|
where(["title LIKE ? or body LIKE ?", "%#{query}%", "%#{query}%"]) if query != ""
}
scope :menu_category_id, lambda { |menu_category_id|
where( "menu_category_id = ?", menu_category_id ) if menu_category_id != ""
}
scope :min_price, lambda { |price|
where("price > ?", price) if price != ""
}
scope :max_price, lambda { |price|
where("price < ?", price) if price != ""
}
end
这是我的控制器(编辑):
class MenuitemsController < ApplicationController
def index
@menuitems = Menuitem.newest_first.filter(params.slice(:menu_category_id, :search_keyword, :min_price, :max_price))
end
这是我的观点:
<%= simple_form_for :menuitem, :method => 'get', :url => {:action => 'index'} do |f| %>
<p>
<%= f.select :menu_category_id, options_for_select(@menucategories.map {|s| [s.title, s.id]}, params[:menu_category_id]), :selected => params[:menu_category_id], :onchange => "this.form.submit();", prompt: "Select category" %>
</p>
<p>
<%= f.input :search_keyword, input_html: { name: 'search_keyword', :value => params[:search_keyword]}, label: 'search recipe title', :required => false %>
<%= f.input :min_price, input_html: { name: 'min_price', :value => params[:min_price]}, label: 'min price:', :required => false %>
<%= f.input :max_price, input_html: { name: 'max_price', :value => params[:max_price]}, label: 'max price:', :required => false %>
<%= f.button :submit, "search" %>
</p>
<% end %>
答案 0 :(得分:1)
通过在范围内添加IF语句,您可以省去控制器中所有组合的所有IF语句的麻烦。例如,这可以类似地应用于与表单关联的四个范围
# menuitem model
scope :search_keyword, lambda { |query|
where(["name LIKE ?", "%#{query}%"]) if query != ""
}
这将允许在控制器中只包含一行,即第一个IF语句下面的行,因为这将处理空白参数。
答案 1 :(得分:0)
类别参数似乎有两个问题。第一个是它是params [:menuitem]中的嵌套参数,所以为了访问它,我们需要调用params [:menuitem] [:menu_category_id]。不太确定为什么这样做是诚实的,尽管我建议在这个例子中使用form_tag而不是form_for,因为我们没有添加或编辑menuitems表本身。
第二个问题是category参数作为字符串传递,而我们需要它作为整数。我们需要在应用之前转换为参数。
现在我不熟悉.filters方法(这是gem的一部分吗?)但是我只是通过将所有范围连接在一起,如下所示,以旧方式工作......
# menuitems controller
def index
@menuitems = Menuitem.newest_first.min_price(params[:min_price]).max_price(params[:max_price]).search_keyword(params[:search_keyword]).menu_category_id(params[:menuitem][:menu_category_id].to_i)
end
注意,更改数据类型的另一种方法是在范围内执行此操作。您可以按照以下方式执行此操作
# menuitem model
scope :menu_category_id, lambda { |menu_category_id|
where( "menu_category_id = ?", menu_category_id.to_i ) if menu_category_id != ""
}