Retaining search results after submitting the search (rails) - ruby-on-rails

I'd like to make it so that after users submit their search, the option they selected stays selected upon the search form's reload. Here's my code for one of these select boxes:
<div><%= f.select :tod_like, Course.tod_array, {:include_blank => true, :selected => params[:search][:tod_like], :class=>"float_and_margin"} %></div>
The key code is the
:selected => params[:search][:tod_like]
When I refresh my page, I get the following error:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
I know I'm getting this error because there's params[:search][:tod_like] is blank. How do I set :selected so that it's blank if the user has not submitted a form, but is the submission, otherwise? I tried using a ternary operator, but that didn't work.
Thanks!

Is the params key correct?
I take it the form f is for an instance of Course so wouldn't it be something like
#course.tod_like = params[:search][:tod_like] ? params[:search][:tod_like] : ""
at the top of the function that generates the search function (you have mentioned that you've tried a ternary statement but did you replace the :selected option at the same time?
Then :selected => #course.tod_like in the select tag?
<div><%= f.select :tod_like, Course.tod_array, {:include_blank => true, :selected => #course.tod_like, :class=>"float_and_margin"} %></div>

Hmm, I ended up fixing this problem by defining a ternary operator in my courses controller, and then passing this instance variable into the appropriate view.
#tod_results = params[:search] == nil ? :blank : params[:search][:tod_like]
<div><%= f.select :tod_like, Course.tod_array, {:include_blank => true, :selected => #tod_results, :class=>"float_and_margin"} %></div>
The key difference between this code and the previous ternary operator I tried is that I'm testing to see if params[:search] is nil, not if params[:search][:tod_like] is nil. Since params[:search] is already nil, I got the "you were expecting an array, but got nil" error when I tried to use params[:search][:tod_like].
Thanks for your responses!

Related

Why is field "line_type_eq" accessible in my view with f.object.line_type_eq but a field called "deleted_eq" always returns nil?

I am using Ransack to search a database with multiple fields. On the view side, I am pre-populating the default field values in my search form with the previous query, which is available in the view, from the controller as #q, using search_form_for #q.
Throughout the form, this is working successfully, but my field called deleted_eq always returns nil when I try to access it with f.object.deleted_eq to check the value. This is despite other field query values being returned properly in the same place using the same format, e.g. f.object.line_type_eq.
Is "deleted" a special field name in Ransack? All fields in my query are working as expected in the controller to return the correct results.
Changing the name of "deleted" would require a database migration and lots of code changes in the project, so I'd hope to check if it is a reserved name before I make all those changes for testing.
Edit for more info:
Rails 5.2.1, Ransack 2.0.1
deleted_eq is a dropdown done with f.select with descriptive text option names that are mapped to 'true', 'false', and ''. So yes, ultimately I believe Ransack is handling it as a boolean.
<%= f.select :deleted_eq, options_for_select([['Active Records', 'false'],
['Deleted Records Only', 'true'], ['Active and Deleted Records', '']],
f.object.deleted_eq || 'false'), {}, { :class => 'form-control',
:onChange => "searchOnchange();" } %>
Figured this out.
It seems like deleted_eq can be nil if a blank value is supplied. I had the most luck adapting another solution I found online like so:
<%= f.select :deleted_eq, [['Active Records', 0], ['Deleted Records', 1]],
{ include_blank: 'All Records', selected: params[:q] ? params[:q][:deleted_eq] : 0 },
{:class => 'form-control', :onChange => "searchOnchange();" } %>
It's a shame that the include_blank option ("All Records") always has to display as the first item in the dropdown, but since I'm able to choose what starts selected, and I can choose "Active Records", it's not the end of the world.

get selected items from select_tag

I have this line in my rails app:
<%= select_tag :questionnaire_id,
options_for_select(#questionnaires_types, #questionnaires_ids),
:multiple => true, :size => 7 %>
which works fine.
but when I try to use the multiple values that were selected I get this:
questionnaire_id"=>["1687,1688,1689,1690,1691,1724"]
instead of this:
questionnaire_id"=>["1687", "1688", "1689" ,"1690", "1691", "1724"]
i.e. I get 1 item instead of 6 items.
any suggestions?
According to rails code: https://github.com/rails/rails/blob/41231ef6c6c6a6e546b69add28f04aafb9e0e952/actionview/lib/action_view/helpers/form_tag_helper.rb#L134
The name must end with [] to be make sure you receive an array.
def select_tag(name, option_tags = nil, options = {})
option_tags ||= ""
html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
if options.delete(:include_blank)
option_tags = content_tag(:option, '', :value => '').safe_concat(option_tags)
end
if prompt = options.delete(:prompt)
option_tags = content_tag(:option, prompt, :value => '').safe_concat(option_tags)
end
content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
end
So just change it to questionnaire_ids[]
Hope that helps.
I think a collection_select would look nice but I cannot help with that since you did not post anything about the model. Maybe try this so that it knows it is a collection:
<%= select_tag "questionnaire_ids[]", options_for_select(#questionnaires_types, #questionnaires_ids), :multiple => true, :size => 7 %>
Or you could just parse the string you currently receive using #split.
Otherwise post a bit more code about the associations between Questionnaire and what ever this model is.
Well, just in case that someone will come to this issue, I found the problem.
It seems to be a bug in rails.
I was using remote_form_for, and that gave me the strange behaviour. I tried to change the form to form_for instead, and I got an array with 6 items.
Rails, Rails, when will you be like .Net? :-(

Rails - Select tag not pre-selected after Form's validation fail

I have select tag
<%= f.select :gender, ["M", "F"], include_blank: "---" %>
If other field has error, the select tag will be reset to "---" even though I have picked an option before.
The solution that I found is using collection_select which takes a ActiveRecord Model to be the option-value pair.
Is there other way to do this?
Thanks
[EDIT]
The answer from #Micah is correct but since my form is Nested, it's different syntax.
Here's my code:
<%= f.fields_for :users do |ff| %>
...
<%= ff.select :gender, ["M", "F"], include_blank: "---",
selected: ff.object.gender ? ff.object.gender : "" %>
...
<% end %>
When I handle errors I usually use render to display the previous page again so I'm going to explain how to handle that first.
When you render a view the params that got passed into your previous command carry over, meaning you'll have params[:object][:gender]as a parameter when you return to the view. Thus
<%= f.select :gender, ["M", "F"], include_blank: "---", selected: params[:object] ? params[:object][:gender] :"" %>
will set the selected value back to what was selected the first time through. Basically what it's doing is taking a conditional and then providing an if/else in the same line. (conditional) ? if true do this : else do this. In this case the conditional is that params[:object] exists (meaning you've attempted to create/edit once before) and if so reassign value otherwise leave blank and select default value, your "---".
If you use redirect_to you'll actually have to manually pass the params back through the redirect but that's fairly simple and just takes the following:
redirect_to new_object_path(params)

Rails check box resetting to default

I have a few check boxes in my view set to default as active:
<%= check_box "product[pr_attributes]", "ag_type", {:checked => #product.issenior?, :multiple => true, :checked => true}, checked_value = "ag:senior", unchecked_value = nil %>Senior(65-100)
The problem is, when I uncheck one of the defaults and save the changes, it defaults back to the checked state. How can I solve this?
Did you mean to have two option keys for :checked?
Mostly like the second one :checked => true is causing your problem.
i think the best way to do this in your case is use check_box_tag since your doing multiple answers for one attribute
syntax
check_box_tag "id", "value", "boolean_if_checked"
so in your case:
<%= check_box_tag "product[pr_attributes][]", "ag_type", #product.issenior?, { } %>
Then just add the other attributes on the hash after the #product.issenior?
This way, you can create multiple checkboxes for pr_attributes, and then when you submit the form, pr_attributes will be an array of your choices.

:prompt appearing in collection_select when a records value is expected

Sorry, this may seem like a simple issue, but: I have a collection_select element that is called via ajax from a _updateregions.html.erb file for creating and editing records that looks like:
<%= collection_select(:wine, :wineregionid, regions, :wineregionid, :regionname,
options = {:selected => :wineregionid, :prompt => "Select a Region"}
) %>
The problem is, when editing an existing record, the prompt is appearing by default instead on the records value. When I remove the :prompt, it works fine... question is, how can I make this work for both the New and Edit case?
According to http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html I think I'm doing it right....
collection_select(object, method,
collection, value_method, text_method,
options = {}, html_options = {})
Returns and tags for
the collection of existing return
values of method for object‘s class.
The value returned from calling method
on the instance object will be
selected. If calling method returns
nil, no selection is made without
including :prompt or :include_blank in
the options hash.
i think :prompt donot takes a string .
it should be true/false or null.
try this
<%= collection_select(:wine, :wineregionid, regions, :wineregionid, :regionname,
options = {:selected => :wineregionid, :prompt => true) %>

Resources