Rails display American date format when using Bootstrap datepicker - ruby-on-rails

I'm trying to use the guidance here to convert my date format in my model. The reason I am doing this is I want my user to see the date format as 7/20/2014, but I need to save that date into the database as 2014-7-20. I tried to implement that with this code, but it is not changing the date format when creating or reading:
class Inquiry < ActiveRecord::Base
belongs_to :user
def date_requested
read_attribute(:date_requested).strftime("%m/%d/%Y")
end
def date_requested=(date_requested)
write_attribute(:date_requested, date_requested.strftime("%Y-%m-%d"))
end
end

Ok, I figured this out. Here's what I did to use American style dates with Bootstrap datepicker:
Add the gem american_date to your gemfile: gem 'american_date'. This gem parses a date as m/d/yy into the format required by the database.
Run bundle install in terminal
Set your form field to show a value rather than what is actually in the database:
<%= f.text_field :requested_date, :value => #inquiry.requested_date.strftime("%m/%d/%Y"), 'data-behaviour' => 'datepicker' %>
Edit your index or show file to display the American format: <%= #inquiry.requested_date.strftime("%m/%d/%Y") %>
This is working great for me.

Related

Rails 4 - Convert datetime into separate date and time fields

How can you convert a mysql datetime field into two form fields (1) date only, (2) time only, and combine both fields back into datetime format on form submit?
This would allow the use of the following gems, but store the dates in a single datetime field:
gem 'bootstrap-datepicker-rails'
gem 'bootstrap-timepicker-rails'
Thanks in advance!
Found the solution with help from #Althaf
Added virtual attributes to model.rb
Used before_save callback to convert back to datetime.
before_save :convert_to_datetime
def sched_date_field
sched_date.strftime("%d/%m/%Y") if sched_date.present?
end
def sched_time_field
sched_time.strftime("%I:%M%p") if sched_time.present?
end
def sched_date_field=(date)
# Change back to datetime friendly format
#sched_date_field = Date.parse(date).strftime("%Y-%m-%d")
end
def sched_time_field=(time)
# Change back to datetime friendly format
#sched_time_field = Time.parse(time).strftime("%H:%M:%S")
end
def convert_to_datetime
self.sched_time = DateTime.parse("#{#sched_date_field} #{#sched_time_field}")
end
Using Rails 4, needed to add sched_date_field and sched_time_field to strong params in controller.rb
Here are the fields in _form.html.erb
<%= f.label :sched_date_field, "Scheduled Date" %>
<%= f.text_field :sched_date_field, :class => "datepicker" %>
<%= f.label :sched_time_field, "Scheduled Time" %>
<%= f.text_field :sched_time_field, :class => "timepicker" %>
You can use date_time_attribute gem:
class MyModel < ActiveRecord::Base
include DateTimeAttribute
date_time_attribute :scheduled_at
end
It will allow you to set schedule_at_date and scheduled_at_time separately. Once attributes are set, values will be combined into schedule_at.
You could use virtual attributes See this Railscast and if you have a pro subscription the revised one.
Basically in the view you would the following
<%= f.label :date_field %>
<%= f.text :date_field %>
<%= f.label :time_field %>
<%= f.text :time_field %>
Your database would still keep a field which I'll call full_date
Now in your model you would have to define the above 2 fields as follows.
def date_field # What this returns will be what is shown in the field
full_date.strftime("%m-%d'%y") if full_date.present?
end
def time_field
full_date.strftime("%I:%M%p") if full_date.present?
end
def time_field=(time)
full_date = DateTime.parse("#{date_field} #{time_field})
end
Since it looks like you are using Rails 4, you'll have to permit date_field and time_field in your strong parameters.
Alternatively, I set up a solution in the controller that does all the datetime conversions before the object gets created, because changing the data in the model impacted all my tests and validations. "Event" is the object I'm creating here with the datetime values being assigned to it.
#In the controller:
def convert_to_datetime_and_assign(event, params)
date_field = Date.parse(params[:date_field]).strftime("%Y-%m-%d")
start_time_field = Time.parse(params[:start_time_field]).strftime("%H:%M:%S")
end_time_field = Time.parse(params[:end_time_field]).strftime("%H:%M:%S")
event.start_time = DateTime.parse("#{date_field} #{start_time_field}")
event.end_time = DateTime.parse("#{date_field} #{end_time_field}")
event
rescue ArgumentError
event.errors.add(:start_time, :invalid, message: "Date or time was invalid")
event
end
in the create and update controller methods I called the method above:
#event = convert_to_datetime_and_assign(#event, event_params)
I added fields for date_field, start_time_field and end_time_field in my forms for creating/updating "events". And in the model I added an accessor to be able to access those values.
attr_accessor :date_field, :start_time_field, :end_time_field

To use the :country input, please install a country_select plugin

I have a country attribute to my guidelines model. I don't want to use a plugin, I just want to have country as a string. Everything is working until I try to edit a guideline in activeadmin and then I get the error message:
ActionView::Template::Error (To use the :country input, please install
a country_select plugin, like this one:
https://github.com/jamesds/country-select):
1: insert_tag renderer_for(:edit)
in my form I have
<%= f.input :country, as: :string%>
in my admin/guidelines.rb I have
index do
column :title
column :specialty
column :content
column :hospital
column :country
column :user
default_actions
end
I'm not sure where you get this form code from but I had the same issue with Active Admin and resolved it by explicitly instructing the form to treat the field as a string:
ActiveAdmin.register Guideline do
form do |f|
f.inputs 'Details' do
f.input :country, :as => :string
end
f.actions
end
end
First you need to add the gem in GemFile
gem 'country-select'
Create a helper file '/app/helpers/active_admin/views_helper.rb'. Add the below code
module ActiveAdmin::ViewsHelper
def country_dropdown
ActionView::Helpers::FormOptionsHelper::COUNTRIES
end
end
In your view file use
form do |f|
f.inputs do
f.input :country, as: :select, collection: country_dropdown
end
f.actions
end
Use country_select. Seems to work fine with Rails 4.1 if you're doing this recently. Plus Rails old repo links to this one rather than country-select.
You're using ActiveAdmin, so you're also using Formtastic.
In Formtastic, in the file formtastic/lib/formtastic/inputs/country_input.rb it clearly says:
# Rails doesn't come with a `country_select` helper by default any more, so you'll need to do
# one of the following:
#
# * install the [country_select](https://github.com/stefanpenner/country_select) gem
# * install any other country_select plugin that behaves in a similar way
# * roll your own `country_select` helper with the same args and options as the Rails one
I would add gem 'country-select' to your Gemfile and do a bundle install as is the simplest and fastest solution.
I guess you could install the gem, and then override the display in active_admin.
I recommend you to use the country-select:
gem 'country-select'
I spent a lot of hours to find out why country-select is not working in my form :)

Rails: Combine 3 select drop-downs to modify 1 attribute of a model

So normally I use the date_select helper in my Rails applications in my Models' forms, but in the most recent application I was building, I needed to specify individual css id's for each drop down (month, day, year), and that isn't possible with date_select. So instead, I've been using select_month, select_day, and select_year helpers. Here's the problem: how do I get them to all describe one datetime record in my database?
(I've looked at this question by the way, but it looks pretty useless to me. Plus, I don't want to do some hacky jQuery stuff handling this.)
Here's what I have so far:
#default_time_for is just a helper method that returns the default time for the specified "period" of time (month,day,etc.)
<%= select_month(default_time_for(:month)) %>
<%= select_day(default_time_for(:day)) %>
<%= select_year(default_time_for(:year), {:start_year => Time.now.year-18, :end_year => 1930}) %>
I'd combine them on the server side:
require 'date'
def update
date = Date.parse(params[:year] + params[:month] + params[:day])
# Add to object and save
end
You can still do mass-assignment, assuming that date is the field you want to assign to, you could do the following:
def update
date = Date.parse(params[:year] + params[:month] + params[:day])
params = params.merge( { :user => { :date => date }})
#user = User.find(params[:id])
if #user.update_attributes(params)
# save was good
else
# save was bad
end
end
Also make sure you're familiar and mitigated against the security issued cased by Mass Assignment if you're going to use the above code.

simple_form input with multiple fields

I'm not quite sure what the correct terms are, but what I'm trying to do is in a form (preferably using the simple_form gem) have one of the inputs, :maximum, use both a text field and select box. The user would type in the text box a number, and then select from a dropdown box of hours, days, or months. So 21 days, 3 months, 3 hours, etc. When the form was submitted I would convert that to days and store it in the database. I know how to change the input type in simple_form, but is it possible to have two inputs for one variable?
Sure :) Here is my idea:
First, you define accessors in your user model:
attr_accessor :thing, :another_thing, :and_another_thing
Then in your view, 'inside' form_for helper, you could write for example:
<%= form.input :thing, :as => :boolean %>
<%= form.input :another_thing, :as => :text %>
...or whatever you want. (Note: I am using formtastic here. You should consider using Rails methods if you're not using formtastic gem. )
Finally, you define a callback in you user model:
before_create :build_my_fancy_record
def build_my_fancy_record
self.storage_field = "#{thing} #{another_thing}"
end

Rails date format in form field

I'd like my dates in the mm/dd/year format in text fields. However, they currently displays as 2010-03-26.
Is there a global setting I can set to change this?
I tried the following, which seems to update the .to_s method, but form fields stay the same.
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:default => '%m/%d/%Y')
Thanks
You have to register the default format in an initializer.
Add this line to the config/initializers/date_time_formats.rb.
Date::DATE_FORMATS[:default] = '%m/%d/%Y'
# if you want to change the format of Time display then add the line below
Time::DATE_FORMATS[:default]= '%m/%d/%Y %H:%M:%S'
# if you want to change the DB date format.
Time::DATE_FORMATS[:db]= '%m/%d/%Y %H:%M:%S'
Now in the script\console lets test the format.
>> Date.today.to_s
=> "03/14/2010"
>> Time.now.to_s
=> "03/14/2010 13:20:55"
I don't know if there is a global setting for that anywhere, I just do it in the ERB.
<%= text_field_tag("air_date_date", air_date.blank? ? "" : air_date.strftime("%m/%d/%Y"), :class => "date-input text") %>
Alternatively, you can factor this out into a helper function to make it DRY.
I know this is an awfully old question, but you could use date_field instead of text_field. Perhaps that wasn't an option when you asked this question originally.
It displays the date in mm/dd/yyyy, which is your intent.
<%= date_field :column_name %>
The date_select form helper provides a "bare bones" date selector.

Resources