Rails:如何使用time_select来节省价值

时间:2016-07-22 08:07:29

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

我正在尝试使用time_select添加include_blank。我这样做:

    <%= f.time_select :start_at, include_blank: true, ampm: true %><br>

如果在视图中选择了空白,我想要删除的值(保存为零?)。

虽然我尝试了以下帖子,但它对我不起作用。

time_select blank field saves a default time when form is submitted

Optional time_select with allow_blank defaults to 00:00

1)当我尝试如下操作时,没有出现错误,但保存了00:00:00

控制器

  def update
    @event = Event.find(params[:id])

    if event_params["start_at(4i)"].blank? or event_params["start_at(5i)"].blank?
      @event.start_at = nil
    end

    if @event.update(event_params)
      flash[:success] = "event updated!"
      redirect_to root_url
    else
      render 'edit'
    end
  end

2)当我尝试如下(更改if子句)时,没有出现错误,但保存了00:00:00

控制器

  def update
    @event = Event.find(params[:id])

    if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
      @event.start_at = nil
    end

    if @event.update(event_params)
      flash[:success] = "event updated!"
      redirect_to root_url
    else
      render 'edit'
    end
  end

3)当我尝试如下(添加before_action)时,没有出现错误,但保存了00:00:00

控制器

  before_action :blank_time,     only: [:update]

  def update
    @event = Event.find(params[:id])

    if @event.update(event_params)
      flash[:success] = "event updated!"
      redirect_to root_url
    else
      render 'edit'
    end
  end

  private

    def blank_time
      if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
        params[:id]['start_at(1i)'] = ""
        params[:id]["start_at(2i)"] = ""
        params[:id]["start_at(3i)"] = ""
        params[:id]["start_at(4i)"] = ""
        params[:id]["start_at(5i)"] = ""
      end
    end

4)当我尝试如下(使用nil而不是"")时,会出现错误。

错误

IndexError (string not matched):
  app/controllers/events_controller.rb:106:in `[]='
  app/controllers/events_controller.rb:106:in `blank_time'

控制器

  before_action :blank_time,     only: [:update]

  def update
    @event = Event.find(params[:id])

    if @event.update(event_params)
      flash[:success] = "event updated!"
      redirect_to root_url
    else
      render 'edit'
    end
  end

  private

    def blank_time
      if params[:id]["start_at(4i)"].blank? or params[:id]["start_at(5i)"].blank?
        params[:id]['start_at(1i)'] = nil
        params[:id]["start_at(2i)"] = nil
        params[:id]["start_at(3i)"] = nil
        params[:id]["start_at(4i)"] = nil
        params[:id]["start_at(5i)"] = nil
      end
    end

如果你能给我任何建议,我将不胜感激。

更新

虽然我更改了events_controller.rb中的修改,但仍会显示错误ActiveModel::MissingAttributeError (can't write unknown attribute 'start_at(4i)'):

  def edit
    @room = Room.find(params[:room_id])
    @event = @room.events.find(params[:id])

    @event['start_at(4i)'] = @event.start_at.split(':')[0]   #the error occur here
    @event['start_at(5i)'] = @event.start_at.split(':')[1]
  end

2 个答案:

答案 0 :(得分:6)

我的想法是这样的:

<强> 迁移:

class CreateTests < ActiveRecord::Migration[5.0]
def change
create_table :tests do |t|
  t.string :time

  t.timestamps
end
end
end

<强> 形式:

<%= form_for(test) do |f| %>
<% if test.errors.any? %>
<div id="error_explanation">
  <h2><%= pluralize(test.errors.count, "error") %> prohibited this test from being saved:</h2>

  <ul>
  <% test.errors.full_messages.each do |message| %>
    <li><%= message %></li>
  <% end %>
  </ul>
</div>
<% end %>

<div class="field">
<%= f.label :time %>
<%= f.time_select :time, include_blank: true, ampm: false %><br>
</div>

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

<强> 控制器: 这将保存:当value send为null时,您可以使用条件来检查参数是否为null或设置时间值。 //它消耗了很多时间,我跳过了你完成。

def create
@test = Test.new(test_params)
@time = (params[:test]['time(4i)']).to_s
@time_ampm = (params[:test]['time(5i)']).to_s
@test.time = @time+":"+ @time_ampm

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

更新

def edit
 @test = Test.find(params[:id])
 @test['time(4i)'] = @test.time.split(':')[0]
 @test['time(5i)'] = @test.time.split(':')[1]
end

def update
  @test = Test.find(params[:id])
  @time = (params[:test]['time(4i)']).to_s
  @time_ampm = (params[:test]['time(5i)']).to_s
  @test.time = @time+":"+ @time_ampm
  @test.update(test_params)
end

答案 1 :(得分:2)

display分配给nil无效,因为在调用@event.starts_at时会使用#event_params中的属性,覆盖您的初始分配。

覆盖params中的starts_at属性应该可以正常工作。

#update

以下行查找并删除def update @event = Event.find(params[:id]) if event_params["start_at(4i)"].blank? or event_params["start_at(5i)"].blank? event_params = event_params.reject { |k, v| k.starts_with? 'starts_at' } .merge(starts_at: nil) end if @event.update(event_params) flash[:success] = "event updated!" redirect_to root_url else render 'edit' end end starts_at(1i)的参数,然后将整个starts_at(5i)属性设置为nil:

starts_at