Rails Setting Null Times on Update - ruby-on-rails-3

I have a Rails 3.2.16 legacy app where I record call information and times on each call en_route_time on_scene_time, etc all are datetime fields.
In my Call show view I have an edit times path which redirects to an edit_times view via a get request. This allows you to edit times in case errors were made.
edit_times in calls_controller.rb
def edit_times
#call = Call.find(params[:id])
end
edit_times.html.erb
<%= form_for(#call) do |f| %>
<%= f.label :En_Route_Time %>
<%= f.date_select :en_route_time %>
<%= f.time_select :en_route_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :On_Scene_Time %>
<%= f.date_select :on_scene_time %>
<%= f.time_select :on_scene_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :To_Hospital_Time %>
<%= f.date_select :to_hospital_time %>
<%= f.time_select :to_hospital_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :At_Hospital_Time %>
<%= f.date_select :at_hospital_time %>
<%= f.time_select :at_hospital_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :In_Service_Time %>
<%= f.date_select :in_service_time %>
<%= f.time_select :in_service_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.button :Submit %>
<% end %>
This works fine, however when editing times if a time is not populated it will update_attributes with a default time when blank is selected 0:00.
So I wrote the following private method in calls_controller' to allow blank times if the5iparams is blank on the update action and use abefore_filter` to trigger it.
calls_controller.rb
before_filter :filter_blank_call_times, only: [:update]
def filter_blank_call_times
if params[:call]['en_route_time(5i)'].blank?
params[:call]['en_route_time(1i)'] = ""
params[:call]['en_route_time(2i)'] = ""
params[:call]['en_route_time(3i)'] = ""
params[:call]['en_route_time(4i)'] = ""
params[:call]['en_route_time(5i)'] = ""
end
if params[:call]['on_scene_time(5i)'].blank?
params[:call]['on_scene_time(1i)'] = ""
params[:call]['on_scene_time(2i)'] = ""
params[:call]['on_scene_time(3i)'] = ""
params[:call]['on_scene_time(4i)'] = ""
params[:call]['on_scene_time(5i)'] = ""
end
if params[:call]['to_hospital_time(5i)'].blank?
params[:call]['to_hospital_time(1i)'] = ""
params[:call]['to_hospital_time(2i)'] = ""
params[:call]['to_hospital_time(3i)'] = ""
params[:call]['to_hospital_time(4i)'] = ""
params[:call]['to_hospital_time(5i)'] = ""
end
if params[:call]['at_hospital_time(5i)'].blank?
params[:call]['at_hospital_time(1i)'] = ""
params[:call]['at_hospital_time(2i)'] = ""
params[:call]['at_hospital_time(3i)'] = ""
params[:call]['at_hospital_time(4i)'] = ""
params[:call]['at_hospital_time(5i)'] = ""
end
if params[:call]['in_service_time(5i)'].blank?
params[:call]['in_service_time(1i)'] = ""
params[:call]['in_service_time(2i)'] = ""
params[:call]['in_service_time(3i)'] = ""
params[:call]['in_service_time(4i)'] = ""
params[:call]['in_service_time(5i)'] = ""
end
end
routes.rb except
resources :calls do
member do
post 'close'
post 'cancel'
post 'note'
get 'opencall'
get 'new_return'
get 'duplicate_call'
get 'edit_times'
put 'update_billing'
post 'dispatch_call'
put 'en_route'
put 'on_scene'
put 'to_hospital'
put 'at_hospital'
put 'in_service'
end
collection do
get "scheduled"
get "call_search"
end
end
This works fine when editing times and allows for a blank time to be entered if the 5i datetime field is blank.
The problem I'm having is when editing/updating a call through the normal edit/update convention, whenever I do edit the call it wipes out whatever times are there.
I'm looking for a way to either write a conditional in the update method in calls_controller.rb where filter_blank_call_times is only called if any of the 5i keys are blank. The way it's working right now is that when you edit times it calls the update action on the calls_controller and sets all of the times to nil. I need to figure out a way to only perform the filter_blank_call_times method when editing times, not when editing/updating a call to prevent call times from being wiped out.
If there is a better way of doing this, such as building another controller for edit_times and nesting that resource under calls or somehow doing a post request instead of utilizing the update action action on the calls_controller I'd love to hear about it.
So in summary, editing times is no problem, but calling this on the update action wipes out the time calls and I need to figure out a way around this.
If my question is not clear or you need more information/code, please let me know.
Here's an except of the params that are passed when calling the update action in calls_controller
Started PUT "/calls/125" for 127.0.0.1 at 2014-10-08 06:59:05 -0500
Processing by CallsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"uH+XDJpZQDH4PNAuOOi7dfLVolfRzziMKWc/rSR6UMg=", "call"=>{"caller_name"=>"James Jelinek", "caller_phone"=>"281-444-2222", "caller_address"=>"", "patient_name"=>"Doe, John", "billing_address"=>"", "patient_dob"=>"2001-10-17", "patient_age"=>"12", "patient_sex_id"=>"1", "insurance_id"=>"4", "nature_id"=>"2", "region_id"=>"2", "transfer_from_id"=>"3", "transfer_from_other"=>"", "facility_from_location"=>"", "transfer_to_id"=>"", "transfer_to_other"=>"123 w 8th st Houston, TX 77088", "facility_to_location"=>"ER Room 2", "service_level_id"=>"1", "special_equipment_ids"=>["", "2"], "transfer_date(2i)"=>"10", "transfer_date(3i)"=>"2", "transfer_date(1i)"=>"2014", "transfer_date(5i)"=>"00:00:00", "wait_return"=>"yes", "parent_call_id"=>"124", "traffic_type"=>"Non-Emergency", "unit_ids"=>["", "1"], "call_status"=>"open"}, "button"=>"", "id"=>"125"}

To check the time against all zeros, nil, or empty this regex should work.
"00:00:00"::=~(/[1-9]/).nil?
=> true
And instead of manually writing everything out you can write code to grab the text before "(5i)" and change all the other values to empty. The code would look something like this:
params["call"].keys.each {|item|
post_text = "(5i)" # Set the target text we're looking for
if !!item[post_text] # If target text matches
if params["call"][item]::=~(/[1-9]/).nil? # Time is all zeros, nil, or empty
pre_text = item[0...item.index(post_text)] # get the text from before target
params["call"].keys.select {|i|
!!i[pre_text] and !i[post_text] #select the OTHER values that match the pre_text
}.each {|like_item|
params["call"][like_item] = "" # set all the OTHER values that match the same pre_text to ""
}
end
end
}
Note if you want to change the (5i) field to blank as well you'd change it to this:
params["call"].keys.each {|item|
post_text = "(5i)" # Set the target text we're looking for
if !!item[post_text] # If target text matches
if params["call"][item]::=~(/[1-9]/).nil? # Time is all zeros, nil, or empty
pre_text = item[0...item.index(post_text)] # get the text from before target
params["call"].keys.select {|i|
!!i[pre_text] #select the values that match the pre_text (including post_text)
}.each {|like_item|
params["call"][like_item] = "" # set all the values that match the same pre_text to ""
}
end
end
}
Either of these get placed inside
def filter_blank_call_times
# CODE HERE
end

Related

Why isn't my search method working in Ruby on Rails?

In my Ruby on Rails application, I have a cinema system and am trying to return the screen a showing is in when a user searches for the showing.
To display the search drop down I am using this code in my _application.html.erb:
<%= render( :partial => '/screen_lookup', :locals => {:showings => #showings = Showing.all, :my_path => '/screens/display_screens_by_showing' })%>
Which renders the search from the _screen_lookup.html.erb:
<%= form_tag my_path, :method=>'post', :multipart => true do %>
<%= select_tag ('showings_id'),
options_from_collection_for_select(#showings, :id, :showing_times, 0 ),
:prompt => "Showings" %>
<%= submit_tag 'Search' %>
<% end %>
And uses the display_screens_by_showing in the screens_controller:
def display_screens_by_showing
#screens = Screen.showing_search(params[:showing_id])
if #screens.empty?
# assign a warning message to the flash hash to be displayed in
# the div "feedback-top"
flash.now[:alert] = "There are no films of that genre."
# return all products, in alphabetical order
#screens = Screen.all
end
render :action => "index"
end
And this searches using the method in the screen.rb model:
def self.showing_search(showing_id)
screen = Showing.where("id = ?", showing_id).screen_id
self.where("id = ?", screen)
end
Now, the problem I am having is that because a showing belongs_to a screen, and a screen has_many showings, I need to be able to search for the showing, and store that showing's screen_id in a variable to search for the screen that showing is in with, which I have tried doing in the model:
screen = Showing.where("id = ?", showing_id).screen_id
self.where("id = ?", screen)
But the error I am getting is:
NoMethodError in ScreensController#display_screens_by_showing
undefined method `screen_id' for #<ActiveRecord::Relation []>
These are the model relationships:
showing.rb:
class Showing < ActiveRecord::Base
belongs_to :screen
end
screen.rb:
class Screen < ActiveRecord::Base
has_many :showings
end
What code will get my search working?
The problem is that where doesn't return a record, it returns a relation that can be enumerated or chained, instead you want to use find or find_by to return a single record, which is kind equivalent to where + first
screen = Showing.find(showing_id).screen_id
which is sort of like doing
screen = Showing.where(id: showing_id).first.screen_id
If you want to pass a hash you can use find_by which will be like this
screen = Showing.find_by(id: showing_id).screen_id
PS:
I'm not sure what you're doing exactly, but i think those two lines can be merged into a single query ( not sure what it should be returning, but I'm assuming a screen )
def self.showing_search(showing_id)
Showing.find(showing_id).screen
end

bootstrap-datepicker-rails, show calendar only on clicking calander-icon(not on text field)

I,m using bootstrap-datepicker-rails gem for date picker and want to shoe calender only on icon click(not on clicking text filed).
Write Now I'm using in my form:
= form_for (ServiceExp.new), :remote => true do |s|
%ul
%li
= s.label :position
= s.text_field :position
%li
= s.label :start_date
%p
From
%li
.input-append.date.datepicker
= s.text_field :start_date, :class =>"input-mini"
%span.add-on
.calander-icon
To
.input-append.date.datepicker
= s.text_field :end_date, :class => "input-mini"
%span.add-on
.calander-icon
%li
= s.label :description
= s.text_area :description
= s.submit 'Save',:class => "btn btn-primary"
And in javascript:
$('.datepicker').datepicker();
Here, Calendar shows on both text field and icon because class datepicker on top of both. If use this class only on icon than it show calender only on icon click but not adding value on text field. How can I achieve that one. please give any suggestion !!
Add :"data-date-format" => 'dd-mm-yyyy', :'data-date' => '12/2/2013' # default date
To div container containing input box and span.
Like
%li
.input-append.date.datepicker{:"data-date-format" => 'dd-mm-yyyy', :'data-date' => '12/2/2013'} # default date
= s.text_field :start_date, :class =>"input-mini"
%span.add-on
.calander-icon

How to Pass Hash parameter of Boolean attribute from view?

I am using Meta-search Gem to search from table by below controller action. I am Using The Rails version 3.2.9.
class FeedEntriesController < ApplicationController
def index
#search = FeedEntry.search(params[:is_star])
#feed_entries = #search.page(params[:page])
#app_keys = AppKey.all
end
end
feed_entries table contain is_star:boolean attribute. So, I just want to pass the hash parameter is_star == true into the params[:is_star] from view using form_for or link_to . I tried using the below way.
In Views/feed_entries/index.html.erb
<%= link_to "Stared", {:controller => "feed_entries", :action => "index", :is_star => true }%>
but the above way is now worked, So I decided to make use of form_for in the below way,
<%= form_for(#is_star) do |f|%>
<%= f.hidden_field :is_star_is_true %>
<%= f.submit "Search" %>
<% end %>
But, nothing is worked, please someone help me resolve this problem.
true and false when passed as a string is parsed as their truthy value when used in a boolean column. This is also true for 0, 1, '0' and '1'
>> m = Model.new
>> m.active = 'false'
>> m.active? # false
>> m.active = 'true'
>> m.active? # true
Knowing this, you can pass 'true' as the value of the hidden_field
<%= f.hidden_field :is_start, value: 'true' %>
You can pass in the value of the parent in the view where the form is being rendere ultimately with something like <%=params[:is_start] = 1 %> . I am not sure how the layout of the app is setup. Also make sure to attr_accessible :is_start
Update: I may have understood your problem wrong. So try this as well
<%= f.hidden_field :is_star, value: 'true' %>
Or you could have a radio button ?
<%= f.radio_button :is_star, value: 'true' %>

Fetch data from date range

I want to see my room_requests which have duration included in my date range from form. Here's what I've done:
controller for this view:
def not_confirmed_slots
if params[:search]
#slots = RoomRequest.find(:all, :conditions => ['date >= ? and date =< ?', params[:start_date].strftime("%Y-%m-%d"), params[:end_date].strftime("%Y-%m-%d")])
if #projects.size.zero?
flash[:notice] = "No result found"
#slots = RoomRequest.find(:all)
end
else
#slots = RoomRequest.all
end
end
and my form from view:
%h1= t('headers.reports.notConfirmedSlots')
= form_tag not_confirmed_slots_reports_path, method: 'get' do
%p
= text_field_tag :start_date, nil, :class => "datepicker", :placeholder => t('placeholders.reports.startDate')
%p
= text_field_tag :end_date, nil, :class=>"datepicker", :placeholder => t('placeholders.reports.endDate')
.clear
.action_bar
= submit_tag t('buttons.reports.generate'), {class: "button blue"}
But every time I submit form with dates it lists me all room_requests from db - any tips?
Oh, and here is the partial (it's on the same view where is search form):
%table
- #slots.each do |s|
%tr
%td
= s.bookers_name
%td
= s.request_type

How do I manually build form data?

I have the following models:
Subject has_many Points
Point belongs_to Subject
Points are created using a form, and the controller is as follows
def create
#subject = Subject.find(params[:subject_id])
#point = #subject.points.build(params[:point])
if #point.save
flash[:success] = "You have created new data"
redirect_to subject_path(#point.subject_id)
else
render 'new'
end
end
At the moment a user can create Points for each Subject using a form. However, I want to also allow the user to upload mass points from a csv file. For this I am using the csv library (ruby 1.9.3)
After uploading the csv file, I put the csv file into a table as follows
thegrid = CSV.table(path, :headers => true, :header_converters => :symbol)
Where path is the path to the csv. The headers for the csv file match the column names in the database (including the subject_id column number)
I want to loop through the rows in the table and add each one to the database as follows
<% point = Hash.new %>
<% thegrid.each do |row| %>
<%
point = {
"name" => row[0],
"total_points" => row[1],
"subject_id" => row[2]
}
%>
<% #point = #subject.points.build(params[point]) %>
<% end %>
But the above doesn't appear to add the rows to the database. What is the correct way to do this loop, I think it may be the params that are causing a problem
I sorted this issue by updating the code as follows:
<%
params[:point] = {
name: row[0],
total_points: row[1],
subject_id: row[2]
}
%>
<% #point = #subject.points.build(params[:point]) %>