How to select options from array with form_tag and checkboxes - arrays

I have an array #sources that contains names (strings) of sources. In a view I want to list every source with a checkbox in a remote form. Then in the linked controller action I would like to have an array in the params hash, containing only those sources, that the user has checked before submitting.
I tried doing that manually, like so:
<%= form_tag select_sources_user_wordsearch_path(#user, #wordsearch), {method: :post, remote: true} do %>
<% #sources.each do |source| %>
<div class="form-group">
<div class="checkbox">
<label class="pull-left">
<input type="checkbox" class="pull-right"> <%=source%>
</label>
</div>
</div>
<% end %>
<div class="form-group">
<%= submit_tag "Start Search",id:"search_commit", class: "btn btn-primary" %>
</div>
<% end %>
But when submitting the form, I don't even see a params hash:
Started POST "/users/1/wordsearches/77/select_sources" for 127.0.0.1 at 2015-08-15 16:18:06 +0200
Processing by WordsearchesController#select_sources as JS
Parameters: {"utf8"=>"✓", "commit"=>"Start Search", "user_id"=>"1", "id"=>"77"}
So I was looking around to see what's going on with the form_tag helper and check_box_tag. And in check_box_tag's API page (see comments) I found that it is possible to pass a collection into it and receive the result of the selection in an array in the params hash. Basically, what I described above.
I am wondering how this would be done inside a form_tag for a remote form, with an array (instead of a collection)?
In the form_tag API page I couldn't find anything about how the data is transferred to the controller. In the check_box_tag there is nothing mentioned about how to handle collections.
Can anyone tell me how this is done "the Rails way"?
It has to be easier than I think..

First question: why don't you use the the form_for helper? Could be something like form_for #wordsearch, url: select_sources_user_wordsearch_path(#user, #wordsearch), {method: :post, remote: true} do.
You may also have a look at the collection_check_boxes helper in the API.
Afaik this can only be used with form_for and the corresponding form object.
<%= form_for #wordsearch do |form| %>
<%= form.collection_check_boxes(:source_ids, #sources, :id, :labeling_method ) %>
<% end %>
Assuming #sources is some kind of an object. In your case
<%= form_for #wordsearch do |form| %>
<%= form.collection_check_boxes(:sources, #sources, :to_s, :to_s ) %>
<% end %>
could work as well. (Did not try it!)
Another way would be to just send the values manually like so:
<% #sources.each do |source| -%>
<%= check_box_tag "wordsearch[sources][]", source -%>
<%= source -%>
<% end -%>
Hope this helps.

Related

How to mark the simple_form checkbox based on a Array object?

The Rails view has two parameters
list_of_attributes = ["a1", "a2", "a3", "a4"]
user_selections = ["a2", "a4"]
I am able to display the appropriate checkboxes and any associated user selections using the following simple_form definition
<% list_of_attributes.each do |item| %>
<label>
<%= check_box_tag "user_selections[]", item, user_selections.include?(item) %>
<%= item %>
</label>
<% end %>
How can I define the above behavior using simple_form f.input syntax? With the following definition, I am able to display the appropriate checkboxes, but any user selections is not 'checked'.
<%= f.input key, as: :check_boxes, collection: list_of_attributes,
:label => key, class: "form-control" %>
Thanks for your help.
Adding checked attribute got the f.input definition functional.
<%= f.input key, as: :check_boxes,
collection: list_of_attributes,
:label => key,
checked: user_selections,
class: "form-control" %>
<% end %>
Try this. This worked for me using bootstrap CSS. Check line 25 in my github repo here
<div class="form-group">
<div class="row">
<div class="col-sm-offset-3 col-sm-8">
<%= f.collection_check_boxes :your_model_ids, Your_model.all, :id, :list_of_attributes do |cb| %>
<% cb.label(class: "checkbox-inline input_checkbox") {cb.check_box(class: "checkbox") + cb.text} %>
<% end %>
</div>
</div>
</div>
And then use this in your CSS file for the custom input_checkbox class above
.input_checkbox input {
width: auto !important;
}

Why is fields_for rendering different indexes in the same form?

I’m using Rails 4.2.3. In my view, I make use of the “fields_for” directive. Notice I use it twice (“f.fields_for :my_object_times”) below …
<div class="field">
<%= f.label "Time" %> <span class="required">*</span><br>
<%= select_tag('my_object[hour]', options_for_select((0..99).to_a.map { |i| i.to_s.rjust(2,'0')}), {:prompt => 'Select Hour'} ) %> hrs
<%= select_tag('my_object[minute]', options_for_select((0..60).to_a.map { |i| i.to_s.rjust(2,'0')}), {:prompt => 'Select Minutes'} ) %> min
<%= select_tag('my_object[second]', options_for_select((0..60).to_a.map { |i| i.to_s.rjust(2,'0')}), {:prompt => 'Select Seconds'} ) %> sec
<%= f.fields_for :my_object_times do |mot| %>
<%= mot.hidden_field :time_in_ms %>
<% end %>
</div>
<div class="field">
<%= f.fields_for :address do |addr| %>
<%= addr.label :address %><br>
City: <%= addr.text_field :city %>
<%= select_tag :state, options_for_select(us_states) %>
<%= country_code_select(:country, :country_id,
nil,
{:include_blank=>false},
{:style=>''}
) %>
<% end %>
</div>
<%= f.fields_for :my_object_times do |rt| %>
<div class="field">
<%= rt.label :overall_rank %><br>
<%= rt.text_field :overall_rank %>
</div>
<div class="field">
<%= rt.label :age_group_rank %><br>
<%= rt.text_field :age_group_rank %>
</div>
<div class="field">
<%= rt.label :gender_rank %><br>
<%= rt.text_field :gender_rank %>
</div>
<% end %>
But when my form gets rendered, the array index on the attributes are displayed differently (one is “0” and the other is “1”) …
<input type="hidden" name="my_object[my_object_times_attributes][0][time_in_ms]" id="my_object_my_object_times_attributes_0_time_in_ms" value="252008000">
…
<input type="text" name="my_object[my_object_times_attributes][1][overall_rank]" id="my_object_my_object_times_attributes_1_overall_rank">
How do I modify my view code so that both attributes get rendered with the “0” index? Note I would prefer to leave the order of my elements on my page exactly as they are.
Two solutions come to mind:
1 - Group your hidden_field (since it's not being shown) with your second form_for which will make it a non-issue and be more elegant.
2 - build your my_object_times object in your controller so when you call the fields_for method you can refer that object which should (I haven't tested it) give it the same reference.
If none of the two options are possible, I'd look at the code and see if there's any way you can refactor to make it work.

get a hash of params with form_tag

I have been looking around for an answer to my problem, without any success so far...
I would like to group some params in hashes after submitting a form, I would like it to look like:
"mysurvey"=>{
{"my question1"=>["my first answer", "my second answer","my third answer"]},
{"my question2"=>["my other first answer", "my other second answer","my other third answer"]}
}
<%= form_tag (#survey) do |f| %>
my first question: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
my second question: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
answer: <%= text_field_tag "survey[mysurvey][]" %>
<%= submit_tag "envoyer" %>
considering mysurvey is the unique attribute of the survey model.
I cannot find a way for grouping each question for their respective answers, is it possible?
If you have any ideas or to solve this problem, let me know!
thank you very much!
Matt
I think you want to take some time to read this section of the form guide: http://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions
It's hard to know from your question the right answer without knowing more about the Model as well but I think what you're looking for is something like this:
my first question: <%= text_field_tag "survey[mysurvey][question1]" %>
answer: <%= text_field_tag "survey[mysurvey][question1][]" %>
answer: <%= text_field_tag "survey[mysurvey][question1][]" %>
answer: <%= text_field_tag "survey[mysurvey][question1][]" %>
my second question: <%= text_field_tag "survey[mysurvey][question2]" %>
answer: <%= text_field_tag "survey[mysurvey][question2][]" %>
answer: <%= text_field_tag "survey[mysurvey][question2][]" %>
answer: <%= text_field_tag "survey[mysurvey][question2][]" %>
However the question element survey[mysurvey][question1] in each answer above depends on how your Model is structured; the rest will give you the data format you are looking for.
A nicer way to possibly loop over your Model is this:
<%= form_for #survey do |survey_form| %>
<%= survey_form.text_field :question %>
<% #survey.questions.each do |question| %>
<%= survey_form.fields_for question, index: question do |question_form|%>
<%= question_form.text_field :answer %>
<% end %>
<% end %>
<% end %>

Unable to traverse one-to-one relationship in Rails

I've got an application where each user has one keyholder, who is allowed to access their account. These are separate models. I've set up the one-to-one relationship within the models, however when I try and use this within the views, I am getting the error of 'undefined method 'id' for nil:NilClass. I've used relationships and traversed them many times before, but I don't understand why this is happening, so please can someone explain?
The only thing that I have done differently from normal is to use Devise to generate the keyholder model rather than scaffolding it as I normally would.
Thanks!
user.rb:
has_one :keyholder
keyholder.rb:
belongs_to :user, dependent: :destroy
And neither of these views work:
keyholders/index.html.erb
<% #keyholders.each do |keyholder| %>
<tr>
<td><%= keyholder.id %></td>
<td><%= keyholder.username %></td>
<td><%= keyholder.user.id %></td>
<td><%= link_to 'Show', keyholder %></td>
<td><%= link_to 'Edit', edit_keyholder_path(keyholder) %></td>
<td><%= link_to 'Destroy', keyholder, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
or keyholder/show.html.erb
<p>
<strong>ID:</strong>
<%= #keyholder.id %>
</p>
<p>
<strong>Username:</strong>
<%= #keyholder.username %>
</p>
<p>
<strong>Keyholder for:</strong>
<%= #keyholder.user.first_name %> <%= #keyholder.user.last_name %>
</p>
<p>
<strong>User ID:</strong>
<%= #keyholder.user.id %>
</p>
Controller code:
def index
#keyholders = Keyholder.all
end
def show
#keyholder = Keyholder.find(params[:id])
end
I tried everything to check where any errors could be - for example checking that both the keyholder's user_id and the user's keyholder_id were both integers etc.
In case anyone is reading this and wants the code to do so, it is:
#model.column_for_attribute('column_name').type
I didn't manage to fix this in the end - luckily I was just starting out with this app, so started again and scaffolded both models before adding Devise to them, and it now works fine having done everything else the same.

Strange Eco Template Behavior

I am using Backbone and Eco templates in my Rails application. My template has the following code:
<% #collection.each (model)-> %>
<% console.log model.get('name') %>
<p><%= model.get('name') %></p>
<p><%= model.get('description') %></p>
<% end %>
For some reason, the HTML is blank. The name and description are not displayed. However, the console.log method outputs the correct data. What am I doing wrong?
Well I figured out the missing character. Apparently, Eco templates require a colon after the arrow:
<% #collection.each (model)->: %>
Not sure why this is the case. It's never mentioned in the readme.

Resources