在多个参数后搜索,Ruby on Rails
Search after multiple parameters, Ruby on Rails
我在 Rails 上对 Ruby 很陌生,我正在尝试创建一个允许用户同时搜索多个参数的搜索功能;从,到。需要记住的是,在开发的后期可能会有更多的参数。我在搜索其中一个字段时可以使用它,但仅此而已。
搜索视图:
<%= form_tag(journeys_path, :method => "get", from: "search-form") do %>
<%= text_field_tag :search_from, params[:search_from], placeholder: "Search from", :class => 'input' %>
<%= text_field_tag :search_to, params[:search_to], placeholder: "Search to", :class => 'input' %>
<%= submit_tag "Search", :class => 'submit' %>
<% end %>
方法:
class Journey < ActiveRecord::Base
def self.search(search_from)
self.where("from_place LIKE ?", "%#{search_from}%")
end
end
控制器:
class JourneysController < ApplicationController
def index
@journeys = Journey.all
if params[:search_from]
@journeys = Journey.search(params[:search_from])
else
@journeys = Journey.all.order('created_at DESC')
end
end
def search
@journeys = Journey.search(params[:search_from])
end
end
我已经尝试了一些我在其他问题中找到的精华和各种解决方案,但我在 RoR 方面还不够好,无法在没有帮助的情况下成功地正确应用它们。如果能得到任何帮助,我将不胜感激。
谢谢!
型号:
class Journey < ActiveRecord::Base
def self.search(search_from, search_to)
self.where("from_place LIKE ? and to_place LIKE ?", "%#{search_from}%", "%#{search_to}%")
end
end
控制器:
class JourneysController < ApplicationController
def index
if params[:search_from] and params[:search_to]
@journeys = search
else
@journeys = Journey.all.order('created_at DESC')
end
end
def search
@journeys = Journey.search(params[:search_from], params[:search_to])
end
end
这里最好的方法是将您的搜索表单封装为一个单独的 Ruby class。在此处使用 Virtus 有助于免费获得类型强制转换。
class SearchForm
include Virtus.model # Our virtus module
include ActiveModel::Model # To get ActiveRecord-like behaviour for free.
attribute :from, String
attribute :to, String
# Just to check if any search param present,
# you could substitute this with validations and just call valid?
def present?
attributes.values.any?{|value| value.present?}
end
```
在 Rails 3 IIRC 中,您还必须包括 ActiveModel::Validations 以便能够在需要时验证您的表单输入。
现在,让我们看看如何重构控制器。我们从参数中实例化表单对象并将其传递给模型查询方法以获取所需的记录。我还移出了 if 子句的排序并使用了符号排序参数 - 更清洁的 IMO。
def index
@search_form = SearchForm.new(search_params)
if @search_form.valid? && @search_form.present?
@journeys = Journey.search(@search_form)
else
@journeys = Journey.all
end
@journeys = @journeys.order(created_at: :desc)
end
def search
@journeys = Journey.search(SearchForm.new(search_params)
end
private
def search_params
params.require(:search_form).permit(:from, :to)
end
现在进入视图:form_for 将与我们的表单对象完美配合,simple_form_for
也是如此
<%= form_for @search_form, url: journeys_path, method: :get do |f| %>
<%= f.text_field :from, placeholder: "Search from", class: 'input' %>
<%= f.text_field :to, placeholder: "Search to", class: 'input' %>
<%= f.submit "Search", class: 'submit' %>
<% end %>
视图现在看起来更短更清晰。在对象中封装参数使得使用搜索参数 muuuuch 更容易。
型号:
class Journey < ActiveRecord::Base
def self.search(search_form)
if search_form.kind_of?(SearchForm)
journeys = all # I'm calling Journey.all here to build ActiveRecord::Relation object
if search_form.from.present?
journeys = journeys.where("from_place LIKE ?", "%#{search_form.from}%")
end
if search_form.to.present?
journeys = journeys.where("to_place LIKE ?", "%#{search_form.to}%")
end
else
raise ArgumentError, 'You should pass SearchForm instance to Journey.search method'
end
end
end
请注意我是如何通过调用 Journeys.all
并应用每个搜索参数(如果存在)来构建 ActiveRecord::Relation 对象的。像这样链接 where
会自动将 AND
放在中间,如果你需要 OR
Rails 4 有它:Journey.or(condition)
。
这种方法的优点:
- 您使用的是 Plain Old Ruby 类,这里几乎没有魔法,它在很多方面都像通常的 Rails 模型一样工作。将搜索参数放入对象中可以更轻松地重构代码。 Virtus 是唯一的依赖项,当然没有 Rails 本身,它更多的是为了方便和避免编写无聊的样板代码。
- 如果需要,您可以轻松验证输入(如果您真的想对输入严格并显示用户验证错误,而不是默默地执行具有矛盾条件且不返回任何结果的愚蠢查询)。
我在 Rails 上对 Ruby 很陌生,我正在尝试创建一个允许用户同时搜索多个参数的搜索功能;从,到。需要记住的是,在开发的后期可能会有更多的参数。我在搜索其中一个字段时可以使用它,但仅此而已。
搜索视图:
<%= form_tag(journeys_path, :method => "get", from: "search-form") do %>
<%= text_field_tag :search_from, params[:search_from], placeholder: "Search from", :class => 'input' %>
<%= text_field_tag :search_to, params[:search_to], placeholder: "Search to", :class => 'input' %>
<%= submit_tag "Search", :class => 'submit' %>
<% end %>
方法:
class Journey < ActiveRecord::Base
def self.search(search_from)
self.where("from_place LIKE ?", "%#{search_from}%")
end
end
控制器:
class JourneysController < ApplicationController
def index
@journeys = Journey.all
if params[:search_from]
@journeys = Journey.search(params[:search_from])
else
@journeys = Journey.all.order('created_at DESC')
end
end
def search
@journeys = Journey.search(params[:search_from])
end
end
我已经尝试了一些我在其他问题中找到的精华和各种解决方案,但我在 RoR 方面还不够好,无法在没有帮助的情况下成功地正确应用它们。如果能得到任何帮助,我将不胜感激。
谢谢!
型号:
class Journey < ActiveRecord::Base
def self.search(search_from, search_to)
self.where("from_place LIKE ? and to_place LIKE ?", "%#{search_from}%", "%#{search_to}%")
end
end
控制器:
class JourneysController < ApplicationController
def index
if params[:search_from] and params[:search_to]
@journeys = search
else
@journeys = Journey.all.order('created_at DESC')
end
end
def search
@journeys = Journey.search(params[:search_from], params[:search_to])
end
end
这里最好的方法是将您的搜索表单封装为一个单独的 Ruby class。在此处使用 Virtus 有助于免费获得类型强制转换。
class SearchForm
include Virtus.model # Our virtus module
include ActiveModel::Model # To get ActiveRecord-like behaviour for free.
attribute :from, String
attribute :to, String
# Just to check if any search param present,
# you could substitute this with validations and just call valid?
def present?
attributes.values.any?{|value| value.present?}
end
```
在 Rails 3 IIRC 中,您还必须包括 ActiveModel::Validations 以便能够在需要时验证您的表单输入。 现在,让我们看看如何重构控制器。我们从参数中实例化表单对象并将其传递给模型查询方法以获取所需的记录。我还移出了 if 子句的排序并使用了符号排序参数 - 更清洁的 IMO。
def index
@search_form = SearchForm.new(search_params)
if @search_form.valid? && @search_form.present?
@journeys = Journey.search(@search_form)
else
@journeys = Journey.all
end
@journeys = @journeys.order(created_at: :desc)
end
def search
@journeys = Journey.search(SearchForm.new(search_params)
end
private
def search_params
params.require(:search_form).permit(:from, :to)
end
现在进入视图:form_for 将与我们的表单对象完美配合,simple_form_for
也是如此<%= form_for @search_form, url: journeys_path, method: :get do |f| %>
<%= f.text_field :from, placeholder: "Search from", class: 'input' %>
<%= f.text_field :to, placeholder: "Search to", class: 'input' %>
<%= f.submit "Search", class: 'submit' %>
<% end %>
视图现在看起来更短更清晰。在对象中封装参数使得使用搜索参数 muuuuch 更容易。
型号:
class Journey < ActiveRecord::Base
def self.search(search_form)
if search_form.kind_of?(SearchForm)
journeys = all # I'm calling Journey.all here to build ActiveRecord::Relation object
if search_form.from.present?
journeys = journeys.where("from_place LIKE ?", "%#{search_form.from}%")
end
if search_form.to.present?
journeys = journeys.where("to_place LIKE ?", "%#{search_form.to}%")
end
else
raise ArgumentError, 'You should pass SearchForm instance to Journey.search method'
end
end
end
请注意我是如何通过调用 Journeys.all
并应用每个搜索参数(如果存在)来构建 ActiveRecord::Relation 对象的。像这样链接 where
会自动将 AND
放在中间,如果你需要 OR
Rails 4 有它:Journey.or(condition)
。
这种方法的优点:
- 您使用的是 Plain Old Ruby 类,这里几乎没有魔法,它在很多方面都像通常的 Rails 模型一样工作。将搜索参数放入对象中可以更轻松地重构代码。 Virtus 是唯一的依赖项,当然没有 Rails 本身,它更多的是为了方便和避免编写无聊的样板代码。
- 如果需要,您可以轻松验证输入(如果您真的想对输入严格并显示用户验证错误,而不是默默地执行具有矛盾条件且不返回任何结果的愚蠢查询)。