Nested Model Form - Render not working - ruby-on-rails

I'm new in rails and need some help creating a Nested form.
I have this in teams/_form.html.erb
<%= form_for #team do |f| %>
<div class="field">
<%= f.label "Name" %><br />
<%= f.text_field :name, :required => true %>
</div>
<%= f.fields_for :players do |builder| %>
<%= render :partial => 'players_field', :f => builder %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I want is create a list of players in the team form. The problem is that the render don't work and players_field.html.erb don't render.
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Position</th>
</tr>
</thead>
<tbody id="tableRow">
<tr>
</tr>
</tbody>
</table>
TR is added to the table with js.
UPDATE:
Another problem appear now :/
This is my js:
var newRow = document.createElement('tr');
newRow.innerHTML = "<td>"+ counter +"</td>"+
"<%= f.text_field :name %>"+
"<%= f.text_field :position %>"+;
document.getElementById("tableRow").appendChild(newRow);
Error:
undefined local variable or method `f' for #<#<Class:0x0000000288dd38>:0x007f77cc1226e0>
Why I can't add this ?

The block
<%= f.fields_for :players do |builder| %>
<%= render :partial => 'players_field', :f => builder %>
<% end %>
is basically a loop through #team.players. It might be the case that #team simply doesn't have any players to loop through. To show the form for at least one player you can change this to
f.fields_for :players, #team.players.build do |builder| ...

Related

Ruby On Rails Basic Show method failed still

In this block of code, i want to put a button "edit" inside the "show" views. However, due to some reason, it did not works out
My home_controller.rb
class HomeController < ApplicationController
def index
#inputs = Person.all
end
def new
#input = Person.new
end
def create
#input = Person.new(input_params)
respond_to do |x|
if #input.save
x.html {redirect_to :action => 'index'}
else
x.html {render :action => 'new'}
end
end
end
def show
#input = Person.find(params[:id])
end
def edit
#input = Person.find(params[:id])
end
def update
#input = Person.find(params[:id])
respond_to do |x|
if #input.update(input_params)
x.html {redirect_to :action => 'index'}
else
x.html {render :edit}
end
end
end
private
def input_params
params.require(:inputs).permit(:name, :weight, :height, :color, :age)
end
end
My routes file only have two lines:
resources: home
root 'home#index'
My index.html.erb
<p id="notice"><%= notice %></p>
<h1>Listing</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th> Weight</th>
<th> Height</th>
<th> Color</th>
<th> Age</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #inputs.each do |person| %>
<tr>
<td><%= person.name %></td>
<td><%= person.weight %></td>
<td><%= person.height %></td>
<td><%= person.color %></td>
<td><%= person.age %></td>
<td><%= link_to 'Show',home_path(person.id) %></td>
<td><%= link_to 'Edit', edit_home_path(person.id) %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Test', new_home_path %>
my show.html.erb:
<p>
<strong>Name:</strong>
<%= #input.name %>
</p>
<p>
<strong>Weight:</strong>
<%= #input.weight %>
</p>
<p>
<strong>Height:</strong>
<%= #input.height %>
</p>
<p>
<strong>Color:</strong>
<%= #input.color %>
</p>
<p>
<strong>Age:</strong>
<%= #input.age %>
</p>
<% link_to 'Edit', edit_home_path(#input) %>
<%= link_to 'Back', home_index_path%>
My form.html.erb
<%= form_for #input, url: {action: "update"} do |person| %>
<div class="field">
<%= person.label :name %><br>
<%= person.text_field :name %>
</div>
<div class="field">
<%= person.label :weight %><br>
<%= person.number_field :weight %>
</div>
<div class="field">
<%= person.label :height %><br>
<%= person.number_field :height %>
</div>
<div class="field">
<%= person.label :color %><br>
<%= person.text_field :color %>
</div>
<div class="field">
<%= person.label :age %><br>
<%= person.number_field :age %>
</div>
<div class="actions">
<%= person.submit %>
</div>
<% end %>
My edit.html.erb
<h1>Editing Data</h1>
<%= render 'form' %>
<%= link_to 'Show', home_path %> |
<%= link_to 'Back', home_index_path %>
The error i get is:
My code <% link_to 'Edit', edit_home_path(#input) %> is point the Edit button to the route home/edit with the obeject #input, that is how i understand it, but it still not working.
Any idea how can i fix this?
Many thanks
The problem is in your show.html.erb. You need to change #person to #input as you have #input defined in your show method

RAILS: Calling a parent model within a nested partial form

Im trying to call a variable from the 'product' model in a 'variant' partial. I can call an existing variable from the 'variant' using:
<%= f.object.product_id %>
But I can't get this to work:
<%= f.object.product.id %>
I can do this:
<%= f.object.product %>
But it returns #<Product:0x007fee2c9a8ec8> and I don't know what to do with it!
Here's a more detailed overview of the situation:
I have 'store' model that has_many 'products'. Each 'product' has_many 'variants'. The variants are nested. Here's the '/store/show.html.erb' file:
<% #store.products.each do |product| %>
<tr>
<td>
<%= form_for(product) do |f| %>
<%= f.fields_for :variants do |builder| %>
<%= render 'variant_fields', f: builder %>
<% end %>
</td>
</tr>
<% end %>
And here's the '/store/_variant_fields' partial:
<fieldset>
</table>
<tbody>
<tr>
<td><%= f.label :variant_name %><%= f.text_field :variant_name %></td>
</tr>
</tbody>
</table>
</fieldset>
the easiest solution would be to pass the product to your partial:
<% render 'variant_fields', f: builder, product: f.object %>
in your partial:
<fieldset>
</table>
<tbody>
<tr>
<td><%= f.label :variant_name %><%= f.text_field :variant_name %><%= product.inspect %></td>
</tr>
</tbody>
</table>
</fieldset>
See what product.inspect shows you.

To pass integer value in render partial form in ruby on rails

I got a task to pass one integer value to another partial form. My code was this
<div class="fields">
<p>
<%= f.label :content, "Student" %><br/>
<%= f.text_field :content %>
<%= link_to_remove_fields "remove", f %><br />
</p>
<h4>Address</h4>
<% i = 1 %>
<% f.fields_for :answers do |builder| %>
<%= render :partial => 'answer_fields', :locals => {:i => i, :f => builder} %>
<% i = i + 1 %>
<% end %>
<p><%= link_to_add_fields "Add Address", f, :answers %></p>
</div>
But in the partial form i got an error like
undefined local variable or method `i'
My partial form is
<p class="fields">
<table>
<tr>
<td>
<%= f.label :content, "Address"+i.to_s %>
</td>
<td>
<%= f.text_field :content %>
</td>
<td>
<%= link_to_remove_fields "remove", f %>
</td>
</tr>
</table>
</p>
How can i pass the value of i to other partial form?
your code is correct.
Please try with this..
<%= render :partial => 'answer_fields', :locals => {:i => i.to_i, :f => builder} %>
I can't see anything wrong with the above code. I even tested this in my rails application in case I was missing something.
You don't have another template that is calling this partial without the :i local do you?

Nested attributes has_many passing and collecting ids to build model

I have this form:
<% form_tag add_expt_details_samples_path, :method => :post do %>
<% for sample in #samples %>
<% if sample.study_id == #study.id %>
<% fields_for "samples[]", sample do |form| %>
<fieldset>
<legend>Sample Name: <%= sample.name %></legend>
<p><center><%= form.label :sample_title %>
<%= form.text_field :sample_title, :size => 25 %></center></p>
<table>
<tr>
<td>
<%= form.label :taxon_id %>
<%= form.text_field :taxon_id, :size => 15 %>
</td>
<td>
<%= form.label :scientific_name %>
<%= form.text_field :scientific_name, :size => 20 %>
</td>
<td>
<%= form.label :common_name %>
<%= form.text_field :common_name, :size => 15 %>
</td>
</tr>
</table>
<p>
<center>
<%= form.label :sample_descripition %><br \>
<%= form.text_area :description %>
</center>
</p>
</fieldset>
<% end %>
<% end %>
<% end %>
<p><center><%= submit_tag "Next" %></center></p>
<% end %>
I would like to collect the samples[] in add_expt_details action so that I could render a post method view for adding new model records for the samples[] ids.
my action is as follows
def add_expt_details
# Collect the samples that were sent
#expt_samples = Sample.find(params[:samples])
# #expt_samples.each do |samp|
# samp.expts.build
# end
end
and then send them to a create action where the sample details are updated and the expt values can be created.
def create_study
#samples = Sample.update(params[:samples].keys, params[:samples].values).reject { |p| p.errors.empty? }
if #samples.empty?
flash[:notice] = "Samples updated"
redirect_to :action => "add_expt_details", :anchor => "ok"
else
render :action => 'edit_individual'
end
end
is there a way to achieve this, I have used accepted_nested_attributes_for :expts, :dependent => :destroy. But I seem to be wrong some where and I do not want to have a form with many fields.
The error message I get is "Unknown key(s): 3, 6, 12"
All suggestions are appreciated.

Find ID does not find the id and create

I have a 2 views that I want to use before the create action.
1st view is add_sample_details.html.erb
<% form_tag add_expt_details_samples_path :method => :post do %>
<% for sample in #samples %>
<% fields_for "samples[]", sample do |form| %>
<fieldset>
<legend>Sample Name: <%= sample.name %></legend>
<p><center><%= form.label :sample_title %>
<%= form.text_field :sample_title, :size => 25 %></center></p>
<table>
<tr>
<td>
<%= form.label :taxon_id %>
<%= form.text_field :taxon_id, :size => 15 %>
</td>
<td>
<%= form.label :scientific_name %>
<%= form.text_field :scientific_name, :size => 20 %>
</td>
<td>
<%= form.label :common_name %>
<%= form.text_field :common_name, :size => 15 %>
</td>
</tr>
</table>
<p>
<center>
<%= form.label :sample_descripition %><br \>
<%= form.text_area :description %>
</center>
</p>
</fieldset>
<% end %>
<% end %>
<p><center><%= submit_tag "Next" %></center></p>
<% for samp in #samples %>
<%= hidden_field_tag("sample_ids[]", samp.id) %>
<% end %>
<% end %>
in the SamplesController, the add_expt_details looks like this
def add_expt_details
# Collect the samples that were sent
#expt_samples = Sample.find(params[:sample_ids])
end
and the add_expt_details.html.erb looks like this
<% form_for #expt_samples, :url => create_study_samples_path, :html => { :method => :put } do |f| %>
<% #expt_samples.each do |samp|%>
<% f.fields_for :expts do |form| %>
<%= form.label :experiment_title %>
<%= form.text_field :expt_title, :size => 15 %><br \>
<% end %>
<% end %>
<p><center><%= submit_tag "Next" %></center></p>
<% end %>
and my create_study action is like this
def create_study
#study = Study.new(params[:study])
# this method collects all the samples from the add_sra_details view from the hidden_field_tag
if current_user.id?
# Put the current user_id in the study.user_id
#study.user_id = current_user.id
if #study.save # Save the values for the study
# Update the Sample attributes
#samples = Sample.update(params[:samples].keys, params[:samples].values).reject { |p| p.errors.empty? }
# For all those sample_ids selected by the user, put the study ids in the sample_study_id
#samples.each do |samp|
#study.samples << samp
end
# get the ids_sent from the add_expt_details
#expt_samples = Sample.find(params[:id])
# A Flash message stating the details would be prefereable..! (Means you have to do it)
flash[:success] = "Your Study has been Created"
redirect_to add_expt_details_samples_path
else
flash[:error] = "Study Faulty"
render :action => "add_sra_details"
end
end
end
The error message I get when I keep the #expt_samples = Sample.find(params[:id]) is "undefined method `keys' for nil:NilClass"
and If I dont have the #expt_samples, it gives me an error "Couldn't Find id in Sample"
Can some one suggest how can I update set of sample ids from one form and also create new Expt model records that are associated to the sample_ids in another form.
All suggestions are appreciated.
Cheers
You need to refer to Rails' accepts_nested_attributes_for
To see how to link existing objects with forms, you can see examples here:
http://josemota.net/2010/11/rails-3-has_many-through-checkboxes/
rails 3 has_many :through Form with checkboxes
has_many through checkboxes

Resources