rails无效日期问题

时间:2017-04-20 02:31:58

标签: javascript ruby-on-rails ruby ruby-on-rails-4

我有一个使用rails 5.0.1的基本预订表单无效,我在提交时收到ArgumentError(无效日期)错误。表格采用开始和结束日期,并提交预订表。

日志显示:

Started GET "/preview?start_date=Wed+May+03+2017+00%3A00%3A00+GMT-0400+(EDT)&end_date=&post_id=3" for ::1 at 2017-04-19 21:47:37 -0400
Processing by ReservationsController#preview as */*
  Parameters: {"start_date"=>"Wed May 03 2017 00:00:00 GMT-0400 (EDT)", "end_date"=>"", "post_id"=>"3"}
  User Load (0.7ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 4 ORDER BY `users`.`id` ASC LIMIT 1
Completed 500 Internal Server Error in 56ms (ActiveRecord: 0.7ms)

ArgumentError (invalid date):

app/controllers/reservations_controller.rb:14:in `parse'
app/controllers/reservations_controller.rb:14:in `preview'

控制器:

class ReservationsController < ApplicationController
    before_action :authenticate_user!, except: [:notify]

    def preload
        post = Post.find(params[:post_id])
        today = Date.today
        reservations = post.reservations.where("start_date >= ? OR end_date >= ?", today, today)
        render json: reservations
    end

    def preview
        start_date = Date.parse(params[:start_date])
        end_date = Date.parse(params[:end_date])

        output = {
            conflict: is_conflict(start_date, end_date)
        }
        render json: output
    end

    def create
      @reservation = current_user.reservations.create(reservation_params)

      if @reservation
        # send request to paypal
          values = {
              business: 'test@test.com',
              cmd: '_xclick',
              upload: 1,
              notify_url: 'http://xyz.ngrok.io/notify',
              amount: @reservation.total,
              item_name: @reservation.post.tool_name,
              item_number: @reservation.id,
              quantity: '1',
              return: 'http://xyz.ngrok.io/your_rentals'
            }
            redirect_to "https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
        else
            redirect_to @reservation.post, alert: "Oops, something went wrong..."
        end
    end

    def notify
      params.permit!
      status = params[:payment_status]
      reservation = Reservation.find(params[:item_number])
      if status == "Completed"
          reservation.update_attributes status: true
      else
          reservation.destroy
      end
      render nothing: true
    end

    def your_rentals
      @rentals = current_user.reservations
    end

    def your_reservations
      @posts = current_user.posts
    end

private

   def reservation_params
      params.require(:reservation).permit(:start_date, :end_date, :price, :total, :post_id)
   end

       def is_conflict(start_date, end_date)
          post = Post.find(params[:post_id])
          check = post.reservations.where("? < start_date AND end_date < ?", start_date, end_date)
          check.size > 0? true : false
       end
end

查看:

<%= form_for([@post, @post.reservations.new]) do |f| %>
  <div class="row">
     <div class="col-md-12 price_tag">
        <span>$<%= @post.price %></span>
        <span class="pull-right">Per Day</span>
     </div>
  </div>
  <div class="row">
    <div class="col-md-6">
       <label>Begin Date</label>
       <%= f.text_field :start_date, readonly: 'true', placeholder: 'Start Date', class: 'form-control' %>
    </div>
    <div class="col-md-6">
       <label>Return Date</label>
       <%= f.text_field :end_date, readonly: 'true', placeholder: 'End Date', class: 'form-control', disabled: true %>
    </div>
  </div>
  <%= f.hidden_field :post_id, value: @post.id %>
  <%= f.hidden_field :price, value: @post.price %>
  <%= f.hidden_field :total, id: 'reservation_total' %>
  <h4><span id="message"></span></h4>
  <div id="preview" style="display: none"> 
     <table class="reservation-table">
       <tbody>
         <tr>
           <td>Day(s)</td>
           <td><span id="reservation_days"></span></td>
         </tr>
         <tr>
           <td>Total</td>
           <td>$<span id="reservation_sum"></span></td>
         </tr>
       </tbody>
     </table><br>
  </div>
  <br>
  <%= f.submit "Book Now", id: "btn_book", class: "btn btn-primary wide", disabled: 'true' %>
<% end %>
<script>
  function unavailable(date) {
    dmy = date.getDate() + "-" + (date.getMonth()+1) + "-" + date.getFullYear();
    return [$.inArray(dmy, unavailableDates) == -1];
   }

  $(function() {
    unavailableDates = [];
    $.ajax({
       url: '/preload',
      data: {'post_id': <%= @post.id %>},
      dataType: 'json',
      success: function(data) {

        $.each(data, function(arrID, arrValue) {
          for(var d = new Date(arrValue.start_date); d <= new Date(arrValue.end_date); d.setDate(d.getDate() + 1)) {
          unavailableDates.push($.datepicker.formatDate('d-m-yy',d));
          console.log(d);
      }
    });

      $('#reservation_start_date').datepicker({
        dateFormat: 'dd-mm-yy',
        minDate: 0,
        maxDate: '3m',
        beforeShowDay: unavailable,
        onSelect: function(selected) {
          $('#reservation_end_date').datepicker("option", "minDate", selected);
          $('#reservation_end_date').attr('disabled', false);

          var start_date = $(this).datepicker('getDate');
          var end_date = $('#reservation_end_date').datepicker('getDate');
          var days = (end_date - start_date)/1000/60/60/24 + 1;
            console.log(days)
          var input = {
            'start_date': start_date,
            'end_date': end_date,
            'post_id': <%= @post.id %>
          }

          $.ajax({
            url: "/preview",
            data: input,
            sucess: function(data) {
              if (data.conflict) {
                $('#message').text("This date range is not available.");
                $('#preview').hide();
                $('#btn_book').attr('disabled', true);
                console.log("end date negative");

              } else {

                $('#preview').show();
                $('#btn_book').attr('disabled', false);

                var total = days * <%= @post.price %>
                $('#reservation_days').text(days);
                $('#reservation_sum').text(total);
                $('#reservation_total').val(total);
                console.log(total);
              }
            }
          }); // end ajax

        }
      });

      $('#reservation_end_date').datepicker({
        dateFormat: 'dd-mm-yy',
        minDate: 0,
        maxDate: '3m',
        beforeShowDay: unavailable,
        onSelect: function(selected) {
          $('#reservation_start_date').datepicker("option", "maxDate", selected);

          var start_date = $('#reservation_start_date').datepicker('getDate');
          var end_date = $(this).datepicker('getDate');
          var days = (end_date - start_date)/1000/60/60/24 + 1;
          console.log(days)

          var input = {
            'start_date': start_date,
            'end_date': end_date,
            'post_id': <%= @post.id %>
          }

          $.ajax({
                url: "/preview",
                data: input,
                sucess: function(data) {
                  if (data.conflict) {
                    $('#message').text("This date range is not available.");
                    $('#preview').hide();
                    $('#btn_book').attr('disabled', true);
                  } else {
                    $('#preview').show();
                    $('#btn_book').attr('disabled', false);
                    var total = days * <%= @post.price %>
                    $('#reservation_days').text(days);
                    $('#reservation_sum').text(total);
                    $('#reservation_total').val(total);
                  }
                    }
               }); // end ajax
            } // end onSelect
          }); // end reservation_end_date
      }
    });
  });
 </script>

型号:

class Reservation < ApplicationRecord
  belongs_to :user
  belongs_to :post
end

2 个答案:

答案 0 :(得分:3)

您在参数中传递了一个空白日期("end_date"=>""),请检查您的日志:

Parameters: {"start_date"=>"Wed May 03 2017 00:00:00 GMT-0400 (EDT)", "end_date"=>"", "post_id"=>"3"}

因此当您执行end_date = Date.parse(params[:end_date])之类的操作时,您会收到错误,因为您正在尝试解析空字符串(或者更准确地说是invalid_date;请检查docs

在使用params[:end_date]之前,您需要首先检查Date.parse是否包含正确的日期格式(或至少不是空白)。

答案 1 :(得分:0)

在您的控制器上使用

start_date = Date::strptime(reservation_params[:start_date], "%m/%d/%y")
end_date = Date::strptime(reservation_params[:end_date], "%m/%d/%y")