我遇到查询问题。我的模型中有一个范围列表:
class Drawing < ActiveRecord::Base
has_many :revisions
scope :by_description, lambda { |description| where('description LIKE ?', "%#{description}%") unless description.nil? }
scope :by_drawing_number, lambda { |drawing_number| where('drawing_number LIKE ?', "%#{drawing_number}%") unless drawing_number.nil? }
scope :by_item_number, lambda { |item_number| where('item_number LIKE ?', "%#{item_number}%") unless item_number.nil? }
scope :by_pump_model, lambda { |pump_model| where('pump_model LIKE ?', "%#{pump_model}%") unless pump_model.nil? }
scope :by_frame_size, lambda { |frame_size| where('frame_size LIKE ?', "%#{frame_size}%") unless frame_size.nil? }
scope :by_part_type, lambda { |part_type| where('part_type LIKE ?', "%#{part_type}%") unless part_type.nil? }
scope :by_created_before, lambda { |created_before| where('created_at <= ?', created_before) unless created_before.nil? }
scope :by_created_after, lambda { |created_after| where('created_at >= ?', created_after) unless created_after.nil? }
我在控制器中的索引操作中调用它们:
def index
@drawings = Drawing.by_description(params[:drawings][:description]).by_drawing_number(params[:drawings][:drawing_number]).\
by_item_number(params[:drawings][:item_number]).by_pump_model(params[:drawings][:pump_model]).by_frame_size(params[:drawings]\
[:frame_size]).by_part_type(params[:drawings][:part_type]).by_created_before(params[:drawings][:created_before]).\
by_created_after(params[:drawings][:created_after]).all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @drawings }
end
end
所有查询都有效,我可以使用它们来过滤任何给定变量的搜索,但by_created_before和by_created_after范围除外。 params哈希显示已输入搜索的日期,但输出的查询不包括这两个范围。这是日志的片段:
Started GET "/drawings?utf8=%E2%9C%93&drawings%5Bdescription%5D=&drawings%5Bdrawing_number%5D=&drawings%5Bitem_number%5D=&drawings%5Bpump_model%5D=&drawings%5Bframe_size%5D
e%5D=&drawings%5Bcreated_before%281i%29%5D=&drawings%5Bcreated_before%282i%29%5D=&drawings%5Bcreated_before%283i%29%5D=&drawings%5Bcreated_after%281i%29%5D=2013&drawings%5B
%5D=5&drawings%5Bcreated_after%283i%29%5D=2&commit=Search" for 127.6.43.1 at 2013-08-31 16:49:56 -0400
Processing by DrawingsController#index as HTML
Parameters: {"utf8"=>"✓", "drawings"=>{"description"=>"", "drawing_number"=>"", "item_number"=>"", "pump_model"=>"", "frame_size"=>"", "part_type"=>"", "created_before(1i
re(2i)"=>"", "created_before(3i)"=>"", "created_after(1i)"=>"2013", "created_after(2i)"=>"5", "created_after(3i)"=>"2"}, "commit"=>"Search"}
Drawing Load (0.6ms) SELECT "drawings".* FROM "drawings" WHERE (description LIKE '%%') AND (drawing_number LIKE '%%') AND (item_number LIKE '%%') AND (pump_model LIKE '%
IKE '%%') AND (part_type LIKE '%%')
Rendered drawings/index.html.erb within layouts/application (11.4ms)
Completed 200 OK in 291ms (Views: 86.7ms | ActiveRecord: 0.6ms)
我也尝试过使用
lambda {|created_before| where(:created_at <= created_before)...}
感谢您的任何建议!
答案 0 :(得分:1)
这是因为您的created_at
和created_before
参数通过多个参数进入 - 请参阅日志中的Parameters:
部分。月,日和年有特殊的(2i)
,(3i)
和(1i)
参数。这是date_select
助手的典型特征。当使用质量分配时,rails会将这个日期重新组合成一个单独的字符串,就像你在这里期待的那样......但是在这里你必须自己做。
快速建议:
如果这是您从表单中使用日期的唯一方法,请使用select_date
instead of date_select
,因为参数更容易理解并再次解析为单个日期字符串。或者,如果可能的话,只使用text_field
。与日期选择的用户界面(日历界面或其他任何东西)相结合,这并不像看起来那么糟糕 - 并且它的优点是似乎不允许无效日期,例如2月31日。
总而言之,你只需要弄清楚哪些参数是哪个,然后在进入你的范围之前将它们插入到一个看日期的字符串中,你应该设置它。
答案 1 :(得分:0)
“params hash显示已输入搜索的日期”。
它在哪里显示?
如果我在URL解码器中解码参数,我会得到“/ drawings?utf8 =✓&amp; drawings [description] =&amp; drawings [drawing_number] =&amp; drawings [ite m_number] =&amp; drawings [pump_model] =&amp; drawings [frame_size] e] =&amp; drawings [created_before(1i)] =&amp; drawings [created_before(2i)] =&amp; drawings [created _before(3i)] =&amp; drawings [created_after(1i) ] = 2013&amp; drawings [] = 5&amp; drawings [created_after(3i)] = 2&amp; commit = Search“
修复输入后,您必须在数据库中进行比较之前将字符串转换为日期。像Datetime.parse params [:drawings] [:created_before]
之类的东西答案 2 :(得分:0)
这是我能够解决问题的方法。 pdobb是正确的,不得不将3个参数放入一个字符串,或单独处理它们。这是我更新的模型:
class Drawing < ActiveRecord::Base
has_many :revisions
scope :by_description, lambda { |description| where('description LIKE ?', "%#{description}%") unless description.nil? }
scope :by_drawing_number, lambda { |drawing_number| where('drawing_number LIKE ?', "%#{drawing_number}%") unless drawing_number.nil? }
scope :by_item_number, lambda { |item_number| where('item_number LIKE ?', "%#{item_number}%") unless item_number.nil? }
scope :by_pump_model, lambda { |pump_model| where('pump_model LIKE ?', "%#{pump_model}%") unless pump_model.nil? }
scope :by_frame_size, lambda { |frame_size| where('frame_size LIKE ?', "%#{frame_size}%") unless frame_size.nil? }
scope :by_part_type, lambda { |part_type| where('part_type LIKE ?', "%#{part_type}%") unless part_type.nil? }
scope :by_created_before, lambda { |x,y,z|
d=Date.new(x.to_i, y.to_i, z.to_i)
d.to_s
where('created_on <= ?', d) unless d.nil? }
scope :by_created_after, lambda { |x,y,z|
d=Date.new(x.to_i, y.to_i, z.to_i)
d.to_s
where('created_on >= ?', d) unless d.nil? }
以及整体查询的最终操作:
def index
@drawings = Drawing.by_description(params[:drawings][:description]).by_drawing_number(params[:drawings][:drawing_number]).\
by_item_number(params[:drawings][:item_number]).by_pump_model(params[:drawings][:pump_model]).by_frame_size(params[:drawings]\
[:frame_size]).by_part_type(params[:drawings][:part_type]).by_created_before(params[:drawings]['created_before(1i)'], params[:drawings]['created_before(2i)'], params[:drawings]['created_before(3i)']).\
by_created_after(params[:drawings]['created_after(1i)'], params[:drawings]['created_after(2i)'], params[:drawings]['created_after(3i)']).all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @drawings }
end
end
我知道这不是最优雅的查询,因为我最终得到了很长的网址,但它的工作正确地查询了我的模型。