Using a Form_for with an each loop - ruby-on-rails

I'm trying to create a form in Rails that allows a user to select certain photos from a larger list using checkboxes. Unfortunately, I haven't found any similar examples and most posts out there are unhelpful. Any ideas on how to solve this?
<div>
<%= form_for :photos, url: trip_path, method: "PUT" do |f| %>
<% #photos.each_with_index do |image, index|%>
<img src="<%= image.url %>" ><br>
<span> <%=image.caption%> | <%=image.lat %> | <%= image.long %>
<%= f.hidden_field "url", :value => image.url %>
<%=check_box_tag('photo') %>
</span>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
</div>

API docs states that a form_for
creates a form and a scope around a specific model object
so, you cannot use it with a collection.
A possible way to do it, is to use the form_tag instead of form_for and check_box_tag (which you already have).

The behavior you've depicted is categorically impossible using form_form. However, if you're willing to forgo form_for (and there's no reason why you shouldn't, given your criteria), you can imitate the behavior depicted by nesting a foreach loop – each loop containing a form_for block – within a form_tag:
<div>
<%= form_tag trip_path, method: "PUT" do |f| %>
<% #photos.each do |photo|%>
<img src="<%= photo.url %>" ><br>
<span> <%= photo.caption%> | <%= photo.lat %> | <%= photo.long %>
<%= fields_for "photos[#{photo.id}]", photo do |p| %>
<%= p.hidden_field 'url', :value => photo.url %>
<%= p.check_box 'photo'
<% end %>
</span>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
</div>

Related

Rails: how to create a list with conditional links

I am working on a RAILS application where I create a view which lists all available resources of a given model species.rb.
The view partial is:
<% i= #s
for species in #species %>
<%= species.name %>, <%= species.author.surname %> <%= species.author.initial_name %>
<% i -= 1
end %>
Some of the resources species have an related article, others have only the name. I would like to loop through the partial and add a link only to the entries which have an associated article.
Something like: add link if species.article is present else just put species.name without link + loop through it for all entries.
How can I do this?
UPDATE:
Thanks to #jvillian and #fool-dev I was able to progress. In my case I wanted to add a link if the resource has a description in a description row of its table.
<% #species.each do |species| %>
<div class="entry">
<p><i><%= link_to_if(species.txtlandscape.present?, "#{species.name}, #{species.author.surname}, #{species.author.initial_name}. 2014", :controller => 'projects', :action => 'show', :id => species) %></i></p>
</div>
<% end %>
Now that a link is added I was wondering if it can be used to load a partial to a target such as in, where ArticleRequest is a JS function I have:
<% # species.each do | species | %>
<div id="species-<%= species.id %>" class="species-entry">
<a onClick="ArticleRequest('/species/show/<%= species.id %>', 'species-<%= species.id %>');">
<p><%= species.name %></p>
</a>
</div>
<% end %>
Until I find a way to do this with link_to_if, I will use something like:
<% for species in #species %>
<% if species.txtlandscape.present? %>
<a onClick="ArticleRequest('/species/show/<%= species.id %>', 'species-<%= species.id %>');">
<p><%= species.name %>, <%= species.author.surname %> <%= species.author.initial_name %></p>
</a>
<% else %>
<p><%= species.name %>, <%= species.author.surname %> <%= species.author.initial_name %></p>
<% end %>
<% end %>
According to the docs, it seems you should be able to do:
<% #species.each do |specie| %>
<%= link_to_if(specie.article, specie.name, specie_article_path(specie.article)) %>
<% end %>
I made the path name up, you'll have to make that match your actual routes.
BTW, this:
for species in #species
Is super non-idiomatic.
You can do this, see the below
<% for species in #species %>
<% if species.article.present? %> #=> I thin it will be articles because table name is articles, anyway, you know better
<%= link_to species.name, link_path(species.article) %>, #=> on the link_path it will be your proper link just replace this
<% else %>
<%= species.name %>,
<% end %>
<%= species.author.surname %> <%= species.author.initial_name %>
<% end %>
You can do this with Rails each method like below
<% #species.each do |species| %>
<% if species.article.present? %> #=> I thin it will be articles because table name is articles, anyway, you know better
<%= link_to species.name, link_path(species.article) %>, #=> on the link_path it will be your proper link just replace this
<% else %>
<%= species.name %>,
<% end %>
<%= species.author.surname %> <%= species.author.initial_name %>
<% end %>
Or you can use link_to_if it is also most easier to understand
<% #species.each do |species| %>
<%= link_to_if(species.article.present?, "#{species.name},", link_path(species.article)) %>
<%= species.author.surname %> <%= species.author.initial_name %>
<% end %>
Hope it will help.

Rails form_for check_box

I'm trying to create a basic survey app. On my take survey page I'm looping through and displaying each answer option as a radio button or checkbox as a form_for to create a user's choice. The choices are working great for the questions that are single choice (or radio buttons), but they aren't saving for multi select questions. I'm pretty sure this has to do with the form I have for the checkbox.
It seems like I should do
<%= f.check_box :answer_id, answer.id %> <%= answer.title %> <br>
similar to how I'm creating the radio button but that throws an error
undefined method `merge' for 14:Fixnum
Here's my code that displays:
<h3>Questions:</h3>
<ul><% #survey.questions.each do |question| %>
<li><p><%= question.title %></p></li>
<% choice = question.choices.build %>
<% if question.single_response == true %>
<%= form_for [question, choice] do |f| %>
<% question.answers.each do |answer| %>
<%= f.radio_button :answer_id, answer.id %> <%= answer.title %><br>
<% end %>
<%= f.hidden_field :survey_id, value: #survey.id %>
<%= f.submit %>
<% end %>
<br />
<% else %>
<%= form_for [question, choice] do |f| %>
<% question.answers.each do |answer| %>
<%= f.check_box :answer_id %> <%= answer.title %> <br>
<%= f.hidden_field :survey_id, value: #survey.id %>
<% end %>
<%= f.submit %>
<% end %>
<br />
<% end %>
<% end %>
</ul>
Any idea what I need to do to get it to save the answer_id to the choice so that it actually creates the choice?
Thanks!
This question is a few years old but I think it deserves a better answer. Since you are using form_for (a model backed form), then you probably want to use the form_for check_box method that you originally tried to use. In your case, it would look like this:
<%= f.check_box :choice, { :multiple => true }, answer.id, false %>
Here is the doc on this.
For checkboxes, you actually want to return an array as the parameter. There is a little funny syntax to this because we don't actually want to use the form builder methods. It should look something like this (adapt to your specific model names and methods)
<%= check_box_tag 'choice[answer_ids][]', answer.id %>
Using this syntax should tell Rails to compile all of the checked checkbox values into an array.
This Railscast goes over the topic.

Rails 4 not rendering code

I am trying to render a partial on a page in rails. For some reason the code is not being rendered into html. I have tried taking it out of the partial and just placing it in the profile page but still nothing. I am getting no errors and have restarted the server but still nothing. This is in development mode. Also all code except the message code works fine. Any help would be appreciated. Here is the code.
profile.html.erb
<% unless #pictures.nil? %>
<div id="container" style="width: 500px; height: 450px;">
<div id="slides">
<% #pictures.each do |picture| %>
<%= image_tag(picture.image.url(:thumbnail)) %>
<% end %>
<%= image_tag("left.png") %>
<%= image_tag("right.jpeg") %>
</div>
</div>
<% end %>
<% render 'message' %>
_message.html.erb
<% form_for #message, :url => messages_create_path do |f| %>
<% f.hidden_field :from, value: current_user.id %>
<% f.hidden_field :to, value: #user.id %>
<% f.text_area :message %><br />
<% f.submit "Send Message" %>
<% end %>
To make your form_for code block to render you need to use <%= tag as follows:
<%= form_for #message, :url => messages_create_path do |f| %>
<% f.hidden_field :from, value: current_user.id %>
<% f.hidden_field :to, value: #user.id %>
<% f.text_area :message %><br />
<% f.submit "Send Message" %>
<% end %>
To elaborate on vinodadhikary's answer, ERB has output tags and evaluation tags. To evaluate something you would use <% expression %>, and to output you would use <%= output.me %>. The earlier is usually used for flow control in templates, and outputs nothing. The output happens within after a decision is made. The latter is used to output stuff.

How to save uncheked check boxes

how i get to save unchecked chekboxes on rails?
I researched some links, but i as unable to find a working solution for me.
i got:
<% #book.each do |book| %>
<div>
<%= check_box_tag "orb[book_ids][]", book.id, #orb.books.include?(book) %>
<%= book.nome %>
</div>
<% end %>
when i uncheck all checkboxes, it didn't save :P
I tried to use a hidden field, but it gave me the error "there no book with id=0"
Add this:
<%= hidden_field_tag 'orb[book_ids][]', '' %>
You form should looks like:
<% #book.each do |book| %>
<div>
<%= check_box_tag "orb[book_ids][]", book.id, #orb.books.include?(book) %>
<%= book.nome %>
</div>
<% end %>
<%= hidden_field_tag 'orb[book_ids][]', '' %>

Unable to pass the params[:fields] hash to controller method in Ruby on Rails

routes.rb
-----------
resources :mail_settings
My form looks like this
the _form.html.erb
---------
<%= form_tag '/mail_settings' do %>
<div class="fieldBlock">
<%= label_tag :name %> <%= text_field_tag :name%> </div>
<div class="fieldBlock">
<%= label_tag :id%> <%= text_field_tag :id%> </div>
<div class="actions fieldBlock">
<%= submit_tag "Update Settings ", :class => "btn-large btn-success" %>
</div>
<% end %>
but I can access individual params like params[:name] without any problem, why is it not working when i try params[:mail_setting] ?
you mean why it is params[:name] and not params[:mail_setting][:name] ? If so, the reason is that you are using form_tag instead of just a form, and family of *_tag helpers [ i.e. text_field_tag ]. In that case you do not 'bind' form to the model - in general form_tag is much more flexible than form. However, You should be able to do something like
<%= text_field_tag "mail_setting[name]"%>
and you will get params[:mail_setting][:name]
Hope I guessed what you asked about!

Resources