首页 > 解决方案 > 为什么当我尝试使用用户输入创建一个 Datetime 对象作为参数时说无效日期

问题描述

所以我很新,我正在尝试创建一个计数器应用程序。所以我的问题是,当我尝试将参数:年、月等传递给 DateTime 对象时,它一直告诉我是一个无效日期。

所以以下是我的控制器类。

class CountersController < ApplicationController
def new
end

def create
  @counter= Counter.new(counter_params)

  @counter.save
  redirect_to @counter
end
private
    def counter_params
        @titulo=params[:titulo]
        @year=params[:year].to_i
        @month=params[:month].to_i
        @day=params[:day].to_i
        @hour=params[:hour].to_i
        @minute=params[:minute].to_i    
        d= DateTime.new(@year,@month,@day,@hour,@minute)
        c_p={"meta"=>d,"titulo"=>@titulo}
    end

结束 在这里输入图片描述

标签: ruby-on-railsdatetimeparameterscounter

解决方案


您可以使用Rails 日期和时间表单助手,而不是重新发明轮子:

<%= form_with(model: counter, local: true) do |form| %>
  ...   
  <div class="field">
    <%= form.label :meta %>
    <%= form.datetime_select :meta %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

这会创建一些非常奇怪的参数:

{"titelo"=>"", "meta(1i)"=>"2018", "meta(2i)"=>"10", "meta(3i)"=>"12", "meta(4i)"=>"18", "meta(5i)"=>"33"}

meta(1i)例如年份。1 是部分并且i是格式(在这种情况下是整数)。

当您允许密钥时,:metaRails 也将允许所有已知的多参数密钥。

(byebug) params.require(:counter).permit(:titelo, :meta)
<ActionController::Parameters {"titelo"=>"", "meta(1i)"=>"2018", "meta(2i)"=>"10", "meta(3i)"=>"12", "meta(4i)"=>"18", "meta(5i)"=>"42"} permitted: true>

并且由于 ActiveRecord 知道该列是日期时间列,因此它将正确分配属性:

irb(main):005:0> Counter.new({"titelo"=>"", "meta(1i)"=>"2018", "meta(2i)"=>"10", "meta(3i)"=>"12", "meta(4i)"=>"18", "meta(5i)"=>"42"})
=> #<Counter id: nil, titelo: "", meta: "2018-10-12 18:42:00", created_at: nil, updated_at: nil>

因此,您在控制器中需要的只是:

class CountersController < ApplicationController
  # ...

  # POST /counters
  # POST /counters.json
  def create
    @counter = Counter.new(counter_params)

    respond_to do |format|
      if @counter.save
        format.html { redirect_to @counter, notice: 'Counter was successfully created.' }
        format.json { render :show, status: :created, location: @counter }
      else
        format.html { render :new }
        format.json { render json: @counter.errors, status: :unprocessable_entity }
      end
    end
  end

  # ...

  private 
  # Never trust parameters from the scary internet, only allow the white list through.
    def counter_params
      params.require(:counter).permit(:titelo, :meta)
    end
end

推荐阅读