现在我可以搜索以下内容
1)leaving_from location
2)going_to location
3)leaving_from& go_to location
if params[:leaving_from].present? && params[:going_to].present?
@flights = Flight.where(:source => params[:leaving_from]).where(:destination => params[:going_to])
elsif params[:leaving_from].present?
@flights = Flight.where(:source => params[:leaving_from])
elsif params[:going_to].present?
@flights = Flight.where(:destination => params[:going_to])
end
上面有代表这个代码的方法吗?基本上它的搜索功能受到2个下拉搜索框的影响。一个用于从位置离开而另一个用于到达位置。可选择通过两个位置或仅一个位置缩小范围。
它现在工作正常,但它不具备可扩展性。如果我添加了更多的搜索参数,例如价格和时间,它将呈指数级增长,以便能够代表所有州。
例如,如果我添加价格,我的新组合将是
1)leaving_from location
2)going_to location
3)leaving_from& go_to location
4)价格
5)leaving_from location&价
6)going_to location&价
7)leaving_from location& go_to location&价
我需要帮助来找出一种更好的方式来表示这一点,否则会让我的控制器变得非常臃肿。
编辑表格代码 -
=form_tag '/flights', :method => :get
%h4
Leaving From:
=select_tag 'leaving_from', content_tag(:option,'select one...',:value=>"")+options_for_select(@flights_source, 'source'), { :class => 'form-control' }
%h4
Going To:
=select_tag 'going_to', content_tag(:option,'select one...',:value=>"")+options_for_select(@flights_destination, 'destination'), { :class => 'form-control' }
%h4=submit_tag "Search", :name => nil, :class => 'btn btn-success btn-md btn-block'
答案 0 :(得分:2)
代替使用leaving_from
或going_to
使用source
和destination
代替并在key
下移动所有必需参数,例如,此解决方案将为任何没有工作。的钥匙
'required' => { 'source' => value, 'destination' => value, 'price' => value }
现在在控制器中私下定义此方法
def get_flights(params)
possible_combination = []
conditions = {}
key_array = params['required'].keys
1.upto(key_array.length) { |i| possible_combination + key_array.combination(i).to_a }
possible_combination.reverse.each do |comb|
if comb.collect{ |key| params['required'][key].present? }.inject(:&)
comb.map { |key| conditions[key] = params['required'][key] }
break
end
end
Flight.where(conditions)
end
从任何操作中调用此方法
@flights = get_flights(params)
希望这有效!它是一个让这个东西变得动态的总体想法,你可以根据你的需要重构代码!
答案 1 :(得分:1)
首先要做的事情是:您的代码没有按照您的想法执行,因为没有办法执行第三个if
(每次第三个if
都是true
,第一个if
也是如此)。关于你的问题:
@flights = Flight
@flights = @flights.where(:source => params[:leaving_from]) if params[:leaving_from].present?
@flights = @flights.where(:destination => params[:going_to]) if params[:going_to].present?
或者
conditions = {}
conditions[:source] = params[:leaving_from] if params[:leaving_from].present?
conditions[:destination] = params[:going_to] if params[:going_to].present?
@flights = Flight.where(conditions)
答案 2 :(得分:0)
使用ransack
如何轻松地将搜索功能添加到搜索功能。
如果您使用ransack
,请写下面的内容。
# View (Search Form)
<%= search_form_for @q do |f| %>
From: <%= f.text_field :leaving_from_cont %>
To : <%= f.text_field :going_to_cont %>
Price:
<%= f.text_field :price_gteq %> 〜 <%= f.text_field :price_lteq %>
<%= f.submit %>
<% end %>
# Controller
def index
@q = Flight.ransack(parmas[:q])
@flights = @q.result(distinct: true)
end
如果用户没有输入任何字段,则hansack不会使用非输入字段值。这意味着不要在DB中添加WHERE
条件。
您还可以使用sort_link
的{{1}}方法轻松对搜索结果进行排序。
请查看ransack
。
答案 3 :(得分:0)
我无法获得@RSB's代码,但我能够使用他的示例创建一个可行的方法。我在行动中调用了以下代码。
@flights = get_flights(search_params)
search_params方法如下:
def search_params
params.permit(:leaving_from, :going_to)
params_hash = {'required' => { 'source' => params[:leaving_from], 'destination' => params[:going_to]}}
end
最后get_flights方法是:
def get_flights(params)
possible_combination = []
conditions = {}
key_array = params['required'].keys
possible_combination = (possible_combination + key_array.combination(key_array.length).to_a).flatten
possible_combination.each do |comb|
conditions[comb] = params['required'][comb] if params['required'][comb].present?
end
Flight.where(conditions)
end
我对ruby和rails仍然很陌生,所以任何反馈或改进建议都会受到欢迎。谢谢!