0

我在查询时遇到问题。我的模型中有一个范围列表:

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 范围。参数哈希显示已输入搜索的日期,但输出的查询不包括这两个范围。这是日志的片段:

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)...}

感谢您的任何建议!

4

3 回答 3

1

这是因为您的created_atcreated_before参数是通过多个参数进入的——请参阅Parameters:那里的日志中的部分。月、日和年以特殊(2i)(3i)、 和(1i)参数输入。这是典型的date_select助手。使用批量分配时,rails 会将日期重新组合成一个字符串,就像您在这里所期望的那样......但是在这里您必须自己做。

一个快速的建议:

如果这是您从表单中使用日期的唯一方法,那么使用select_date而不是date_select作为参数将更容易理解并再次一起解析为单个日期字符串。或者,text_field尽可能使用 a 。结合日期选择 UI(日历界面或其他),这并没有看起来那么糟糕——而且它的优点是不允许出现无效日期,例如 2 月 31 日。

总而言之,您只需要弄清楚哪些参数是哪些参数,然后在传递到您的范围之前将它们插入到一个看起来像日期的字符串中,您就应该进行设置。

于 2013-08-31T21:54:09.663 回答
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

我知道这不是最优雅的查询,因为我最终得到了很长的 URL,但它可以正常工作并正确查询我的模型。

于 2013-09-01T04:26:22.973 回答
0

“参数哈希显示已输入搜索的日期”。

它在哪里显示这个?

如果我在 URL 解码器中解码参数,我会得到 "/drawings?utf8=✓&drawings[description]=&drawings[drawing_number]=&drawings[ite‌​m_number]=&drawings[pump_model]=&drawings[frame_size] e]=&drawings [created_before(1i)]=&drawings[created_before(2i)]=&drawings[created‌​_before(3i)]=&drawings[created_after(1i)]=2013&drawings[]=5&drawings[created_after(3i)]=2&commit=Search"

修复输入后,您必须先将字符串转换为日期,然后再在数据库中进行比较。类似 Datetime.parse params[:drawings][:created_before]

于 2013-08-31T21:53:59.950 回答