I am a new ROR user trying to implement a DateTime picker to select dates for a search function.
My problem is that when I enter two dates (date from, and date to) in the DatePicker, I get inconsistent results from the search. Sometimes I get no results, and sometimes I get all the results. I am also using the bootstrap-datepicker-rails gem as well as the ransack gem.
This is what my view looks like
<div class="field">
<%= f.label :departure_date_gteq, "Departure Date Between" %>
<%= f.search_field :departure_date_gteq, "data-provide" => "datepicker" %>
<%= f.label :return_date_lteq, "and" %>
<%= f.search_field :return_date_lteq, "data-provide" => "datepicker" %>
</div>
The two database columns I am referencing are departure_date, and return_date. The date stored is datetime and looks like this,
departure_date
2016-08-07 00:00:00.000000
return_date
2016-08-14 00:00:00.000000
I enter 2016-08-06 and 2016-08-15 in the DatePickers and I am returned all the results.
Could my search form DatePicker be sending data that cannot be correctly compared to the DateTime in the database?
Am I using the 'gteq' and 'lteq' calls correctly?
EDIT #1
#Michael Gaskill, you are correct that the problem is the date formatting. When I enter a date manually, I get the correct search results. I just need to figure out how to correct the formatting before its passed to the controller.
Here is what my controller looks like.
class HomeController < ApplicationController
def index
#search = Sailing.search(params[:q])
#sailings = #search.result
... Other calls ...
end
end
Here is the full piece of code in my view that generates sailings content. Note that I'm using search_for_for which is part of the ransack gem.
<%= search_form_for #search, url: root_path, method: :post do |f| %>
<div class="field">
<%= f.label :cruise_ship_name_or_cruise_ship_company_or_destination_identifier_cont, "Cruise Ship Name" %>
<%= f.text_field :cruise_ship_name_or_cruise_ship_company_or_destination_identifier_cont %>
</div>
<div class="field">
<%= f.label :departure_date_gteq, "Departure Date Between" %>
<%= f.search_field :departure_date_gteq, "data-provide" => "datepicker" %>
<%= f.label :return_date_lteq, "and" %>
<%= f.search_field :return_date_lteq, "data-provide" => "datepicker" %>
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
Thanks.
You need to convert the string-formatted dates entered in the form (either via the DatePicker or manually-entered) to Date or DateTime values. When you query the database, use this DateTime#strptime to convert:
MyTable.where(date_field_to_search: DateTime.strptime(date_value_from_ui, "%F %T")
You can check out the formats available as the second argument to strptime, using the instructions at DateTime:strftime. Note that strftime and strptime are used to convert back and forth between DateTime and formatted String values.
In your Sailing#search(params[:q]) example, you can either implement the solution in Sailing#search (if you have access to change that code) or prior to calling Sailing.search.
Here is how you might implement this in Sailing#search:
class Sailing
def search(args)
datetime = args[:date_field_to_search]
if datetime.kind_of?(String)
datetime = DateTime.strptime(datetime, "%F %T")
end
# other search functionality
end
end
or, prior to calling Sailing#search:
datetime = params[:q][:date_field_to_search]
if datetime.kind_of?(String)
datetime = DateTime.strptime(datetime, "%F %T")
end
Sailing.search(params[:q].merge({ date_field_to_search: datetime })
Related
By design, some classes will deal with only a subset of available languages.
the globalize-accessors gem is quite useful, however, the rendering requires that the following be defined
Class.globalize_attribute_names
so while available_locales = [:en, :ru, :fr, :de], the goal is to work with a smaller array [:en, :ru]
The documentation states Calling globalize_accessors with no options will therefore generate accessor methods for all translated fields and available languages. But the purported way to invoke is in the model
globalize_accessors :locales => [:en, :fr], :attributes => [:title]
How can the globalize_accessorsmethod refer to an array, something generated by the likes of
#post.owner.ownerlocales.pluck('locale')
(although the array values are quoted...)
A working solution found but that does not address the above question, is based on the fact that globalize-accessors
gives you access to methods: title_pl, title_en, title_pl=, title_en=
Thus, a controller method that generates a whitelist
#locales = []
#post.owner.ownerlocales.each do |ol|
locale = ol.locale
#locales.push(locale)
end
... then process in the view filtering out the globalize_processors from whitelist
<% Post.globalize_attribute_names.each do |lang| %>
<% my_string = lang.to_s %>
<% #locales.each do |locale| %>
<% checkstring = "_" + locale %>
<% if my_string.include? checkstring %>
<div class="row">
<%= t(lang[0..-4]) %> - <%= lang[-2, 2] %> <br />
<%= f.text_area lang, rows: "3" %>
</div>
<% end %>
<% end %>
<% end %>
Not efficient, functional.
I have the following code
<%= form_tag('/update', method: :post) do %>
<%= select_tag :role, UserSomething.roles.keys.map {|role| [role.titleize,role]} %>
Role is an enum which text values have to be displayed in the drop down menu, and on form submit, i have to send the index of selected enum to some controller. I don't know how to set select_tag propertly.
I would use the helper options_for_select to map the array you get from UserSomething.roles.keys.map to a list of options for the select. I don't think out the select_tag method handles an array of the box, it needs a list of option tags. See the docs here.
<%= form_tag('/update', method: :post) do %>
<%= select_tag :role, options_for_select(UserSomething.roles.keys.map {|role| [role.titleize,role]}) %>
<% end %>
I have a sample model in which belongs_to a patient model.Using rails-jquery-autocomplete I have managed to implement an autocomplete field where one can search patient's code and it works well. However when editing the form, the patient code is empty on the form.
How should I fix it?
App/views/sample/_form.html.erb
<div class="field">
<%= f.label :patient_code %><br>
<%= f.hidden_field :patient_id, id: 'patient_id' %>
<%= f.autocomplete_field :patient_code, autocomplete_patient_code_samples_path, id_element: '#patient_id' %>
</div>
I faced the same issue while editing the saved model, a quick workaround would be as follows:
...
<%= f.autocomplete_field :patient_code, autocomplete_patient_code_samples_path, id_element: '#patient_id', value: (!#sample.new_record?)? #sample.patient.code : '' %>
...
Assuming that the instance variable is #sample. Modify it according to your scenario. Cheers!
I am at the moment creating a complicated rails form for 1:n relationship with nested form and collection select with values from yet another data table.
So far, it overwrites the database value with the first entry in the values list of the collection_select whenever the user does not select the correct value before update. I still need to set the initial value in the collection_select correctly.
I have read a lot of questions on SO already, most relevant was:
f-collection-select-not-displaying-the-selected-value
The only thing still missing (I hope!), is the setting of the value of the form field from the database, so it does not get overwritten with a default value from the selects selectable values, even though the user has not touched the select.
This snippet is derived from my code and the solution to the abovementioned question and is wrong.
Let a person have many things and validthings contains the possible values for things:
In the things table there will only be Thing strings, that are also in the validthings table. It is possible to give the collection_select selected param a string from the things table that can be identified in the list of values from the validthings table.
<div class="col-md-12">
<%= form_for(#person) do |f| %>
<%= f.fields_for :things do |d| %>
<%= d.hidden_field :id %><%= d.hidden_field :person_id %>
<%= d.collection_select(:Thing, Validthings.all, :Thing, :Thing, {:selected => #person.things.map(&:id).Thing.to_s} ) %>
<% end %>
<% end %>
</div>
This is what is wrong:
#person.things.map(&:id).Thing.to_s
And yes, in tables persons and things and validthings the column is named "Thing". It is a unique string in table validthings - the database structure was not my idea, I only work with it.
Found a helpful answer here: rails-accessing-current-value-of-a-symbol
to another subject, but my problem was that I did not know how to access the information that I knew must already be loaded.
This is how I can specify the default value of a collection_select to be the data from the database:
<div class="col-md-12">
<%= form_for(#person) do |f| %>
<%= f.fields_for :things do |d| %>
<%= d.hidden_field :id %><%= d.hidden_field :person_id %>
<%= d.collection_select(:Thing, Validthings.all, :Thing, :Thing, {:selected => d.object.Thing} ) %>
<% end %>
<% end %>
</div>
where d.object.Thing is the value of the respective object of the form element for the attribute "Thing", which is already present in the form.
I'd be very grateful for constructive ideas, in case my approach is un-ruby-like or some such. I am rather new to ruby, rails etc.
I am trying to implement the acts_as_taggable_on gem. In my set up I have a Model called Discipline which is pre-populated with about 40 names.
I also have a Model Micropost which I want to tag - using a select box containing all the names in the disciplines database. I thought that I could call the acts_as_taggable_on the Model I wanted - in this case Disciplines but its not working with my current set up.
class Micropost < ActiveRecord::Base
acts_as_taggable
acts_as_taggable_on :disciplines
end
Here is the form......
<%= simple_form_for(#micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.input :tag_list, :as => :select,
:multiple => :true,
:collection => ActsAsTaggableOn::Tag.pluck(:name) %>
<%= f.text_area :content, placeholder: "What is your question?", :style => "height:75px;" %>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
I can tell from the documentation that there is a way to do this....but I guess I am just not getting it. Any suggestions?
I don't think you can use acts_as_taggable_on using a model other than the default Tag and Taggings models.
Alternative Approach #1
Seed your database with the pre-populated 40 Tags containing your discipline names.
Alternative Approach #2
Use bitmask_attributes for your 40 disciplines.
For example, in my application I have:
bitmask :instruments, as: [:others, :guitar, :piano, :bass, :mandolin, :banjo,
:ukulele, :violin, :flute, :harmonica, :trombone,
:trumpet, :clarinet, :saxophone, :viola, :oboe,
:cello, :bassoon, :organ, :harp, :accordion, :lute,
:tuba, :ocarina], null: false