In my Rails app I have a nested form_for in my show action. This form is the same as the one in the edit action, but it has different fields.
Category -> Task -> completed (boolean, check_box) is what I am trying to update, but it doesn't. Although, if I do Category -> Task -> name (string, text_field) it updates fine.
This does NOT work
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :completed, check_list.tasks[count].name %>
<%= task.check_box :completed %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
This works
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :name, check_list.tasks[count].name %>
<%= task.text_field :name %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
This is a partial, and check_list is a variable I'm passing
Edit:
Here is the source for my models:
class CheckList < ActiveRecord::Base
has_many :tasks, :dependent => :destroy
accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
# Validations
validates :name, :presence => true
end
class Task < ActiveRecord::Base
belongs_to :check_list
end
I'd suggest adding the name as a hidden field on the form, as Rails probably updates all the fields that are passed into the Action.
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :completed, check_list.tasks[count].name %>
<%= task.check_box :completed %>
<%= task.hidden_field :name %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
Related
In my rails app I have a questions view that renders all the questions in a poll. I want to make sure that all the questions rendered can be submitted using 1 submit button.
If that's not possible, how can I render one question after another until there are no more quesitons?
The front-end code goes:
poll_question.html.erb:
<% #poll.questions.each do |qst| %>
<%= render "questions" , qst: qst%>
<p style="color: red"><%= notice %></p>
<hr>
<% end %>
Render partial _questions.html.erb:
<%= form_with model: qst.question_results.build, url: question_question_results_path(qst) do |f| %>
<% qst_type = qst.poll.voting_type %>
<% option_length = qst.options.count %>
<%= f.hidden_field :question_id, value: qst.id %>
<%= f.hidden_field :option_id, value: qst.options.first.id %>
<h3> <%= qst.title %></h3>
<h6> <%= qst.description %> </h6>
<ul>
<% qst.options.each do |option| %>
<%= f.fields_for :question_result_ranks, f.object.question_result_ranks.build do |rank_f| %>
<%= rank_f.hidden_field :option_id, value: option.id %>
<%= option.title %>
<%= rank_f.select :rank, options_for_select((1..option_length).step(1)) %><br>
<% end %>
<% end %>
</ul>
<div>
<%= f.submit "Save Answer" %>
</div>
<% end %>
Here is my routes.rb
resources :users do
resources :polls
# Questions
resources :questions, shallow: true do
resources :options
resources :question_results
patch "/create_question_results", to: "questions#create_question_results", as: "create_question_results"
end
end
Edit: These views are not rendered under the Poll and Question Controller, They are rendered under the session module which has no relationships in the model.
If you want to submit all the questions with one click, you should use a nested form.
Main template poll_question.html.erb:
<%= form_with model: #poll do |form| %>
<%= form.fields_for :questions do |f| %>
# This block renders a collection of partials.
<%= render 'question', f: %>
<% end %>
<%= form.submit 'Save' %>
<% end %>
Question form _quiestion.html.erb:
<% qst = f.object %>
<% qst_type = qst.poll.voting_type %>
<% option_length = qst.options.count %>
<%= f.hidden_field :question_id, value: qst.id %>
<%= f.hidden_field :option_id, value: qst.options.first.id %>
<h3> <%= qst.title %></h3>
<h6> <%= qst.description %> </h6>
<ul>
<% qst.options.each do |option| %>
<%= f.fields_for :question_result_ranks, f.object.question_result_ranks.build do |rank_f| %>
<%= rank_f.hidden_field :option_id, value: option.id %>
<%= option.title %>
<%= rank_f.select :rank, options_for_select((1..option_length).step(1)) %><br>
<% end %>
<% end %>
</ul>
And don't forget to add accepts_nested_attributes_for :questions in your poll model.
Hi I am using gem 'carmen-rails' in my app I am having this type of association
class Employee < ActiveRecord::Base
has_one :contact
has_one :permanent_address
accepts_nested_attributes_for :contact, :permanent_address
end
and in my employess_controller.rb I have define like this:
def subregion_options
render partial: 'subregion_select'
end
and in my routes :
resources :employees do
collection do
get 'subregion_options'
end
end
In my employees/new.html.erb
<%= form_for #employee do |f| %>
<label class="form_label">Email</label>
<%= f.text_field :email %>
<label class="form_label">Set Ex Employee</label>
<%= f.check_box :is_active %>
<%= f.fields_for :contact do |c| %>
<label class="form_label">Address 1</label>
<%= c.text_field :current_address1 %>
<%= c.country_select :country,:prompt => 'Select Country' %>
<%= render partial: 'subregion_select', locals: {parent_region: c.object.country} %>
<% end %>
<%= f.submit %>
<% end %>
in employees/_subregion_select.html.erb
<div id="order_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:contact, :state_code, parent_region) %>
<% else %>
<%= text_field(:contact, :state_code) %>
<% end %>
</div>
In js file
$('select#employee_contact_attributes_country').change(function() {
selectWrapper = $('#order_state_code_wrapper');
countryCode = $(this).val();
url = "/employees/subregion_options?parent_region=" + countryCode;
selectWrapper.load(url);
});
But its not fetching any states. Please guide how to solve this. Thanks in advance.
Essentially, I have a binary voting system Like/Dislike. Thee class is called Like It has polymorphic associations to likeable:
class Like < ActiveRecord::Base
belongs_to :likeable, polymorphic: true
end
and we have the class Comment, which also has polymorphic associations to commentable and can be liked
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
has_many :likes, :as :likeable
end
We have the class Section, which can also be liked and commented on
class Section < ActiveRecord::Base
has_many :likes, as: :likeable
has_many :comments, as: commentable
end
However, on the page section#show I display the Section information, the section likes, and then the comments (from a comments/comments partial). Here is the Section#show view:
<h1><%= exercise.name %></h1>
<p><%= exercise.description %></p>
<%= render 'likes/like_button' %>
<%= render 'comments/comments' %>
<%= render 'comments/comment_form' %>
However, I want the ability to vote on each comment.
The following code is from the _comments.html.erb - What currently doesn't work is the rendering of the _like_button.html.erb because it doesn't apply to the comment at hand.
<% #comments.each do |comment| %>
<%= comment.content %>
<%= render 'likes/like_button' %>
<hr />
<% end %>
And here is the _like_button.html.erb partial
<% if #like.nil? %>
<%# No record of Like in table %>
<%= form_for [#likeable, Like.new] do |f| %>
<%= f.submit "Like" %>
<%= f.submit "Dislike" %>
<% end %>
<% else %>
<%# Marks current chosen option, if the opposite option is chosen, the record is updated to reflect the descion by the user %>
<%= form_for [#likeable, #like] do |f| %>
<% if #like.is_liked %>
Currently Liked!
<%= f.submit "Dislike" %>
<% else %>
<%= f.submit "Like" %>
Currently Disliked!
<% end %>
<% end %>
<% end %>
So ultimately, I just want to know how to make it possible to vote on a comment from within the Section#show view
Thanks!
Try this:
<% #comments.each do |comment| %>
<%= comment.content %>
<%= render 'likes/like_button', :like => comment.like, :likeable => comment %>
<hr />
<% end %>
<% if like.nil? %>
<%# No record of Like in table %>
<%= form_for [likeable, Like.new] do |f| %>
<%= f.submit "Like" %>
<%= f.submit "Dislike" %>
<% end %>
<% else %>
<%# Marks current chosen option, if the opposite option is chosen, the record is updated to reflect the descion by the user %>
<%= form_for [likeable, like] do |f| %>
<% if like.is_liked %>
Currently Liked!
<%= f.submit "Dislike" %>
<% else %>
<%= f.submit "Like" %>
Currently Disliked!
<% end %>
<% end %>
<% end %>
On a single page I might have a single Video and then checkboxes to add multiple dogs to it. Easy enough (as follows)...
View:
<%= check_box_tag "video[dog_ids][]", dog.id %>
Controller:
params[:video][:dog_ids] ||= []
But what I can't figure out how to do is have multiple videos, each with multiple dogs.
I currently have this:
<% #videos.each do |video| %>
<%= fields_for "item[]", video do |f| %>
<%= f.hidden_field :id, :index => nil %>
<%= f.text_field :title, :index => nil%>
<%= f.text_area :body, :index => nil %>
<% video.dogs.each do |dog| %>
<%= check_box_tag "item[][video[dog_ids][]]", dog.id %>
<% end %>
<% end %>
<% end %>
But when I do that, dogs_ids is always nil when it's submitted.
Any idea what I'm doing wrong?
Such a setup with fields_for "item[]" and f.text_field :title, :index => nil produces:
<input id="item__name" name="item[][title]" size="30" type="text" value="vid1">
This indicates that the checkbox name should be item[][dog_ids][].
A working example:
<% #videos.each do |video| %>
<%= fields_for "item[]", video do |f| %>
<%= f.text_field :title, :index => nil %>
<% video.dogs.each do |dog| %>
<%= check_box_tag "item[][dog_ids][]", dog.id %> <%= Dog.name %>
<% end %>
<br>
<% end %>
<% end %>
This produces result in params:
{"item"=> [
{"title"=>"vid1", "dog_ids"=>["1", "2"]},
{"title"=>"vid2", "dog_ids"=>["2"]},
{"title"=>"vid3", "dog_ids"=>["2", "3"]}
]}
i would like to use an additional collection for a fields_for. this collection should hold all the possibilities to be used in fields_for.
Lets say I have a person with tasks that will happen regularly each week on the same day. In the person form, i should have an entry for each day, even if there are not yet any saved tasks. I tried:
<% form_for(#person) do |f| %>
...
<% f.fields_for :tasks, #weekdays do |task_fields| %>
<%= weekday.name %>:
<%= project_fields.text_field :name %>
<% end %>
<% end %>
now there should be for each weekday a text field to enter the name of the task of that day. for example weekday.name = "monday" and task.name = "drinking coffee", task.weekday_id = 1
You are not iterating through the week_days. You should do like this:
<% #weekdays.each_with_index do |weekday, i| %>
<% f.fields_for :tasks do |task_fields| %>
<%= weekday.name %>:
<%= task_fields.text_field :name %>
<%= task_fields.hidden_field :weekday_id, :value => (i + 1) %>
<% end %>
<% end %>
If you have a table 'weekdays', then hidden_field value should be weekday.id
Edit: July 30
I think I completely messed up this answer. Let me try to improve it.
<% f.fields_for :tasks, #weekdays do |task_fields| %>
<%= weekday = task_fields.object %>
<%= weekday.name %>:
<%= task_fields.text_field :name %>
<%= task_fields.hidden_field :weekday_id, :value => weekday.id %>
<% end %>