【问题标题】:searching records between start date and end dates for ransack搜索开始日期和结束日期之间的记录以进行洗劫
【发布时间】:2013-04-09 06:44:58
【问题描述】:

您好,我正在使用 ransack + kalendae_assets gem 搜索开始日期和结束日期之间的记录 为此,我通过引用使用 ransack PREDICATES https://github.com/ernie/ransack/blob/master/lib/ransack/constants.rb

这是我的代码

<%= search_form_for @search, url: guest_search_rooms_path, html: {:method =>:post} do |f| %>
  <%= f.label :start_date_eq , "Start Date"%>   
  <%= f.text_field :start_date_eq, class: 'release_date' %>     

  <%=f.label :end_date_eq, "End Date" %>   
  <%= f.text_field :end_date_lteq, class: 'release_date' %>     
  <%= f.submit "search" %>
<% end %>

rooms.controller

def guest_search 

  @search = Room.search(params[:q])
  @roome = @search.result(:distinct => true)
  @room= @roome.where("status IS ?", true).order("room_type_id desc")

  #@room = @search.result(:distinct => true)
 end 

但是当我输入开始和结束日期时,它不会搜索我该怎么做

【问题讨论】:

  • 显示@room.to_sql的输出
  • 虽然该日期范围内有很多记录,但它显示空白什么都没有显示任何内容
  • @room.to_sql 应该返回 activerecord 用来检索数据的查询。试试 'Room.search(params[:q]).result.to_sql'。
  • 不,这不起作用。它给了我 NoMethodError 错误(nil:NilClass 的未定义方法“结果”)
  • @r15 你有没有找到解决方案?我正在寻找类似的实现。

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 ransack


【解决方案1】:

使用https://github.com/dangrossman/bootstrap-daterangepicker,您可以进行日期范围搜索:

= search_form_for q, url: orders_path, builder: SimpleForm::FormBuilder do |f|
  = f.input :daterange , input_html: {value: "#{q.date_gteq.to_s} - #{q.date_lteq.to_s}"}
  = f.input :date_gteq, as: :hidden
  = f.input :date_lteq, as: :hidden

:coffee
  $ ->
    $('#q_daterange').daterangepicker
      format: "YYYY-MM-DD"
      startDate: $('#q_date_gteq').val()
      endDate: $('#q_date_lteq').val()
      ranges:
        'This Week': [moment().startOf('week'), moment().endOf('week')],
        'Next Week': [moment().add('week', 1).startOf('week'), moment().add('week', 1).endOf('week')]
    , (start, end, label) ->
      $('#q_date_gteq').val start.format("YYYY-MM-DD")
      $('#q_date_lteq').val end.format("YYYY-MM-DD")
    .on 'apply.daterangepicker', -> $('#order_search').submit()

【讨论】:

  • 谢谢伙计,这正是我所需要的。
【解决方案2】:

您可以自定义谓词。

在我看来,我有一个类似的搜索字段

= f.text_field :request_date_between, class: 'daterange'

这将向控制器发送一个日期,如

'2015-10-01 至 2015-10-31'

然后在我肮脏的 ransack.rb 初始化程序中我有;

Ransack.configure do |config|
  config.add_predicate 'between',
                       arel_predicate: 'between',
                       formatter: proc { |v| v.split(' to ') },
                       type: :string
end

module Arel
  module Predications
    def between other
      gteq(other[0]).and(lt(other[1]))
    end
  end
end

【讨论】:

    【解决方案3】:

    让between 谓词识别本地时区,在ransack.rb 初始化器中...

    Ransack.configure do |config|
      config.add_predicate 'between',
                           arel_predicate: 'between',
                           formatter: proc { |v| Range.new(*v.split(' to ').map { |s| Time.zone.parse(s) }) },
                           type: :string
    end
    

    无需覆盖Arel::Predications#between。

    (这仅适用于日期时间列类型。)

    标题

    【讨论】:

    • 完美运行。谢谢。
    【解决方案4】:

    您可以将范围与开始日期和结束日期一起使用。然后你可以得到日期之间的搜索结果。以下是搜索表单中的示例代码:

    <div class="control-group">
        <%= f.label :scrap_date_cont, "Scrap Date", class: 'control-label' %>
        <div class="controls">
          <% if q.scrap_date_cont.blank? %>
        <%= f.text_field :scrap_date_cont, include_blank: true, default: nil, :class => 'datepicker3', :style=>"width:100px;" %> 
          <% elsif !q.scrap_date_cont.blank? %>
          <%= f.text_field :scrap_date_cont, :value => "#{change_date_format_for_edit_page(q.scrap_date_cont)}", :class => 'datepicker3', :style=>"width:100px;" %> 
          <% end %>&nbsp;<%= link_to "Select Range", "#", :id => 'dates' %> 
    
        </div>
      </div>
    
    
         <div class="control-group" id="range" style="display:none" >
            <%= f.label :scrap_date_gteq, "Range", class: 'control-label' %>
    
            <div class="controls">
              <% if q.scrap_date_gteq.blank? %>
              <%= f.text_field :scrap_date_gteq, include_blank: true, default: nil, :class => 'datepicker1', :style=>"width:100px;" %>
              <% elsif !q.scrap_date_gteq.blank? %>
              <%= f.text_field :scrap_date_gteq, :value => "#{change_date_format_for_edit_page(q.scrap_date_gteq)}", :class => 'datepicker1', :style=>"width:100px;" %> 
              <% end %>
    
               <% if q.scrap_date_lteq.blank? %>
              <%= f.text_field :scrap_date_lteq, include_blank: true, default: nil, :class => 'datepicker2', :style=>"width:100px;"  %>
               <% elsif !q.scrap_date_lteq.blank? %>
               <%= f.text_field :scrap_date_lteq, :value => "#{change_date_format_for_edit_page(q.scrap_date_lteq)}", :class => 'datepicker2', :style=>"width:100px;" %> 
               <% end %>
            </div>
          </div>
    

    这是控制器代码:

    params[:q][:scrap_date_cont] = change_date_format(params[:q][:scrap_date_cont]) if !(params[:q][:scrap_date_cont]).blank?
        params[:q][:scrap_date_cont] =  params[:q][:scrap_date_cont].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_cont]).blank?
        params[:q][:scrap_date_gteq] = change_date_format(params[:q][:scrap_date_gteq]) if !(params[:q][:scrap_date_gteq]).blank?
        params[:q][:scrap_date_gteq] =  params[:q][:scrap_date_gteq].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_gteq]).blank?
           params[:q][:scrap_date_lteq] = change_date_format(params[:q][:scrap_date_lteq]) if !(params[:q][:scrap_date_lteq]).blank?
         params[:q][:scrap_date_lteq] =  params[:q][:scrap_date_lteq].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_lteq]).blank? 
    

    助手代码:

    #Change date format in edit time
     def change_date_format_for_edit_page(date)
        new_date = date.strftime("%m/%d/%Y")
        puts new_date.inspect
        return new_date
      end
    

    脚本:

    $("#dates").click(function () {
      var $that = $(this);
      $("#range").toggle("slow", function() {
        $that.toggleClass("toggled-off");
      });
    });
    

    我想这可能对你有帮助...

    【讨论】:

      【解决方案5】:

      就我而言,我确实是这样的:

      只需传递一个日期,它将从开始搜索到该日期的结束。

      初始化程序/ransack.rb

      Ransack.configure do |config|
        config.add_predicate 'between_begin_and_end',
                         arel_predicate: 'between_begin_and_end',
                         formatter: proc { |v| v.to_date },
                         validator: proc { |v| v.present? },
                         type: :string
      end
      
      module Arel
        module Predications
          def between_begin_and_end date
            gteq(date.to_date.beginning_of_day).and(lt(date.end_of_day))
          end
        end
      end
      

      查看

      <%= f.text_field :date_field_here_between_begin_and_end, class: 'datepicker', placeholder: 'yyyy/mm/dd' %>
      

      【讨论】:

        【解决方案6】:

        这是一个带有下拉菜单的解决方案,用于选择日期范围。我们将添加一个between 谓词并传递一个格式化为字符串的日期时间范围,如下所示:

        (5.days.ago..5.days.from_now).to_s
        
        => "2021-05-30 15:21:05 +0200..2021-06-09 15:21:05 +0200"
        

        首先添加一个 Ransack between 谓词,依赖于原生的 between Arel 谓词。 formatter 获取该字符串值并将其拆分为 '..',将开始/结束日期转换为 DateTime 并构建一个范围。

        # config/initializers/ransack.rb
        Ransack.configure do |config|
          config.add_predicate 'between',
            arel_predicate: 'between',
            formatter: proc { |v| Range.new(*v.split('..').map{ |s| DateTime.parse(s) }) },
            validator: proc { |v| v.present? },
            type: :string
        end
        

        在模型或视图模型或助手中,定义选择的选项:

        # app/helpers/rooms_helper.rb
        module RoomsHelper
          def rooms_search_ranges
            now = Time.current
            next_month = 1.month.from_now
            {
              "This month" => now.beginning_of_month..now.end_of_month,
              "Next month" => next_month.beginning_of_month..next_month.end_of_month
            }
          end
        end
        

        在你的表单中,假设你的模型有一个booked_at 属性:

        <%= search_form_for @search, url: guest_search_rooms_path, html: {:method =>:post} do |f| %>
        
          <%= f.select :booked_at_between, rooms_search_ranges %>
        
          <%= f.submit "search" %>
        <% end %>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-05
          • 2021-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多