Rimil Dey
Rimil Dey

Reputation: 977

Rails - :date and :time columns show nil value

I am new to rails, and I have moved a front-end project to the rails environment. I have set up a form with start_date, end_date and start_time columns. start_date and end_date have the column type :date and start_time has the column type :time. I am using a date picker to select the dates and time picker to select the time. The format in which I am receiving both the date and time is:

Wed Jan 11 2017 13:31:14 GMT+0530

I have formatted the output using moment js to show a more comprehensible date and time format to the user.

moment().format('LL'); //January 23,2017
moment().format('LTS'); //1:17:54 PM

On submitting the form, the date and time columns are nil.

I have read that I should use Date.parse() and Time.parse() or strftime to convert the dates.

I have two questions: 1. Where should I put the code for the conversion? By intuition, I think it should either be in the controller, or maybe in the view, while taking the input itself. 2. What is the format the :date and :time column accept?

I have sqlite 3 as the database for ActiveRecord and I am using Rails 5.0.1.

home.new.html.erb (form fields for the three column type):

 <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
            <%= f.text_field :start_date,:class => "mdl-textfield__input"%>
            <label class="mdl-textfield__label" for="home_start_date" id="start-date-label">Enter start date</label>
          </div>


          <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
            <%= f.text_field :end_date,:class => "mdl-textfield__input"%>
            <label class="mdl-textfield__label" for="home_end_date" id="end-date-label">Enter end date</label>
          </div>

          <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
            <%= f.text_field :start_time,:class => "mdl-textfield__input"%>
            <label class="mdl-textfield__label" for="home_start_time" id="start-time-label">Enter time</label>
          </div>

home_controller.rb

class HomeController < ApplicationController
  def index
    @campaigns = Home.all
  end

  def new
    @home = Home.new
  end

  def show
    @campaign = Home.find(params[:id])
  end

  def create
    home_params = params.require(:home).permit(:campaign_name,:phone_number_receiver,:start_date,:end_date,:start_time,:sms_msg)
    @home = Home.new(home_params)
    @home.save
  end
end

Link to github : https://github.com/rimildeyjsr/sms-scheduler

Upvotes: 0

Views: 706

Answers (1)

ReggieB
ReggieB

Reputation: 8247

You should process the data in the controller - or if there is a lot of data processing to be done, or the processing rules are complicated: have the controller hand the processing to a dedicated data processing object.

I'd suggest modifying your controller code like this:

def create  
  @home = Home.create(home_params)
end

private

def home_params
  home_params = params.require(:home).permit(
    :campaign_name, :phone_number_receiver, :start_date, :end_date,    
    :start_time, :sms_msg
  ).tap do |attr|
    attr[:start_date] = Date.parse(attr[:start_date])
    attr[:end_date] = Date.parse(attr[:end_date])
    attr[:start_time] = Time.parse(attr[:start_time])
  end
end

tap allows you to step into the params hash as it is being processed via require, and modify it's content.

If the processing was complicated, you could do something like:

def home_params
  home_params = params.require(:home).permit(
    :campaign_name, :phone_number_receiver, :start_date, :end_date,    
    :start_time, :sms_msg
  ).tap do |attr|
    ParamsProcessor.modify attr
  end
end

Where ParamsProcessor is an object you create to handle the processing. For example:

module ParamsProcessor
  def self.modify(hash)
    hash.each do |key, value| 
      hash[key] = Date.parse(value) if /_date$/ =~ key && value.present?
      hash[key] = Time.parse(value) if /_time$/ =~ key && value.present?
    end
  end
end

Upvotes: 2

Related Questions