2016-07-22 21 views
10

我正在嘗試將time_selectinclude_blank相加。我這樣做:Rails:如何不使用time_select節省價值

<%= 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 

如果你能給我一些建議將不勝感激。

UPDATE

雖然我改變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

分配@event.starts_at爲零什麼都不做在#event_params屬性調用#update時,覆蓋您最初的分配使用。

覆蓋params中的starts_at屬性應該可以改爲工作。

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),然後將整個starts_at屬性是零:

event_params.reject { |k, v| k.starts_with? 'starts_at' }.merge(starts_at: nil)

+0

感謝您的快速反應,@Ivan。雖然我還沒有充分理解你的答案,但是當我嘗試時會顯示以下錯誤。 'NoMethodError(未定義方法'拒絕'nil:NilClass):'。並且在'def update'中添加代碼是否正確? – SamuraiBlue

+0

是的,您應該刪除您的before_action並將其添加到更新方法(在第一個示例的if空白子句中)。 – Ivan

+0

我編輯了答案以顯示完整的方法。 – Ivan

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 %> 

控制器: 這將保存:當值發送是空的,你可以使用條件來檢查,如果參數爲空或與設定時間值。 //消耗很多時間,我跳過完成。

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 
+0

謝謝你的回答,@Pradeep Sapkota。保存在數據庫中的值是'00:00:00'而不是'null'。我想知道在'time_select'選擇空白時如何保存'null'。 – SamuraiBlue

+0

answwer更新檢查它。 –

+0

如果您希望將null作爲默認值,最好將其存儲在字符串中。 –