例如在我的Car模型中我有这样的字段:
color, price, year
以形式partial我生成包含所有这些字段的表单。但是如何编写这样的逻辑:
用户可以输入颜色和年份,我必须找到这个条件,用户可以同时输入一年或所有字段......
如何写出条件?我可以这样写:
if params[:color].present?
car = Car.where(color: params[:color])
end
if params[:color].present? && params[:year].present?
car = Car.where(color: params[:color], year: params[:year])
end
and so over....
但这是一个非常难看的解决方案,我是铁杆的新手,想知道:如何更好地解决我的问题?
答案 0 :(得分:4)
查看has_scope gem:https://github.com/plataformatec/has_scope
它确实简化了很多:
class Graduation < ActiveRecord::Base
scope :featured, -> { where(:featured => true) }
scope :by_degree, -> degree { where(:degree => degree) }
scope :by_period, -> started_at, ended_at { where("started_at = ? AND ended_at = ?", started_at, ended_at) }
end
class GraduationsController < ApplicationController
has_scope :featured, :type => :boolean
has_scope :by_degree
has_scope :by_period, :using => [:started_at, :ended_at], :type => :hash
def index
@graduations = apply_scopes(Graduation).all
end
end
来自控制器方面
答案 1 :(得分:2)
我会把它们变成你的Car模型的范围:
scope :by_color, lambda { |color| where(:color => color)}
scope :by_year, lambda { |year| where(:year => year)}
在您的控制器中,您只需将它们有条件地链接起来:
def index
@cars = Car.all
@cars = @cars.by_color(params[:color]) if params[:color].present?
@cars = @cars.by_year(params[:year]) if params[:year].present?
end
答案 2 :(得分:1)
user_params = [:color, :year, :price]
cars = self
user_params.each do |p|
cars = cars.where(p: params[p]) if params[p].present?
end
答案 3 :(得分:0)
我会这样做的典型(天真但简单)方法是在我的模型中使用通用search
方法,例如
class Car < ActiveRecord::Base
# Just pass params directly in
def self.search(params)
# By default we return all cars
cars = all
if params[:color].present?
cars = cars.where(color: params[:color])
end
if params[:price1].present? && params[:price2].present?
cars = cars.where('price between ? and ?', params[:price1], params[:price2])
end
# insert more fields here
cars
end
end
您可以轻松地将where
链接到这样的查询上,并且Rails将在SQL中将它们全部组合在一起。然后,您可以使用Car.search(params)
调用它。
答案 4 :(得分:-1)
我认为你可以使用params.permit
my_where_params = params.permit(:color, :price, :year).select {|k,v| v.present?}
car = Car.where(my_where_params)
编辑:我认为这仅适用于rails 4,不确定您使用的是哪个版本。
编辑#2摘自我链接到的网站:
如果允许的属性丢失,使用许可证不会介意
params = ActionController::Parameters.new(username: "john", password: "secret")
params.permit(:username, :password, :foobar)
# => { "username"=>"john", "password"=>"secret"}
正如您所看到的,foobar并不在新哈希中。
EDIT#3将select块添加到where_params,因为在注释中指出空表单字段会触发在params散列中创建一个空元素。