an error in forms and rendering ruby on rails 3 - ruby-on-rails

I am creating a form for submitting student details in the first step and in the second step parent (guardian) details should be submitted.
I have created a controller for student and another for the guardian, after filling the details , i need when pressing on submit button at first step , the step two should appear which is parent/guardian details but i am having a problem in achieving this. and my files are:
students_controller.rb
class StudentsController < ApplicationController
def index
#student = Student.all
end
def show
#student = Student.find(params[:id])
end
def new
#student = Student.new
end
def create
#student = Student.new(params[:student])
if #student.save
flash[:success] = ' Student Record Saved Successfully. Please fill the Parent Details.'
render 'guardians/new'
else
flash.now[:error] = 'An error occurred please try again!'
render 'new'
end
end
def edit
end
end
student.rb
class Student < ActiveRecord::Base
attr_accessible :address_line1, :address_line2, :admission_date, :admission_no, :birth_place, :blood_group, :city,
:class_roll_no, :date_of_birth, :email, :first_name, :gender, :language, :last_name, :middle_name,
:phone1, :phone2, :post_code, :religion, :country_id, :nationality_id
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :batch
belongs_to :nationality , class_name: 'Country'
has_many :guardians , foreign_key: 'ward_id'
has_many :student_previous_subject_marks
has_one :student_previous_data
end
guardians_controller.rb
class GuardiansController < ApplicationController
def index
end
def show
end
def new
#guardian = Guardian.new
end
def edit
end
end
guardian.rb
class Guardian < ActiveRecord::Base
attr_accessible :city, :dob, :education, :email, :first_name, :income, :last_name, :mobile_phone, :occupation,
:office_address_line1, :office_address_line2, :office_phone1, :office_phone2, :relation
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :ward , class_name: 'Student'
end
routes.rb
Triton::Application.routes.draw do
get "guardians/index"
get "guardians/show"
get "guardians/edit"
get "students/index"
get "students/show"
get "students/edit"
resources :articles do
resources :comments
end
resources :users
resources :guardians
resources :students
resources :sessions
get '/user/dashboard', to: 'static_pages#home'
get '/student/admission1' , to: 'students#new'
get '/student/admission2' , to: 'guardians#new'
root to: 'sessions#new'
end
students/new.html.erb
<h1>Admission</h1>
<h4>Step 1 - Student details</h4>
<div>
<div class="span6 offset2">
<%= form_for(#student) do |f| %>
<% if #student.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#student.errors.count, 'error') %>
</div>
<ul>
<% #student.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :admission_no %></div></th>
<th><div class="field"><%= f.text_field :admission_no %></div></th>
</tr>
<tr>
<th><div class="field"><%= f.label :admission_date %></div></th>
<th><div class="field"><%= f.text_field :admission_date , :class => 'datepicker'%></div></th>
</tr></table>
<h4>Student - Personal Details</h4>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :first_name %></div></th>
<th><div class="field"><%= f.text_field :first_name %></div></th>
</tr>
<tr>
guardians/new.html.erb
<h1>Admission</h1>
<h4>Step 2 - Parent details</h4>
<div class="row-fluid">
<div class="span4 offset1 hero-unit">
<%= form_for #guardian do |f| %>
<% if #guardian.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#guardian.errors.count, 'error') %>
</div>
<ul>
<% #guardian.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<div class="field">
<%= f.label 'Student Admission number' %>
<%= f.text_field :ward_id , disabled: true %>
</div>
<h4>Parent - Personal Details</h4>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
//not the whole file, just copied what is needed to be seen
the error i am facing
NoMethodError in Students#create
undefined method `model_name' for NilClass:Class
Extracted source (around line #45):
42:
43: <div class="row-fluid">
44: <div class="span4 offset1 hero-unit">
45: <%= form_for #guardian do |f| %>
46: <% if #guardian.errors.any? %>
47: <div id="error_explanation">
48: <div class="alert alert-error">
I hope you can get my point to solve my problem and thanks !!

This could be a few things:
Change the line from:
<%= form_for #guardian do |f| %>
to:
<%= form_for :guardian => {:action => :create} do |f| %>
If this doesn't work. delete the line {:action => :create}
other things that might be the problem.
You have two controllers and haven't said which is the relevant one.
Neither of your controllers is setting the plural #guardian referenced in your view

You should
redirect_to new_guardian_url
instead of
render 'guardians/new'
inside your students_controller.rb

Related

How to save nested form data in Rails?

I have this data inside my foods and drinks table:
Foods table
ID | Name
------------
1 | Rojak
2 | Lemang
Drinks table
ID | Name
------------
1 | Barli
2 | Sirap
My model relationship is:
class Survey < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions, allow_destroy: true
end
class Question < ActiveRecord::Base
belongs_to :survey
has_many :answers
accepts_nested_attributes_for :answers, allow_destroy: true
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :foods
has_many :drinks
accepts_nested_attributes_for :foods, :drinks
end
class Food < ActiveRecord::Base
belongs_to :answer
end
class Drink < ActiveRecord::Base
belongs_to :answer
end
And this is my _form.html.erb file inside app/views/surveys:
<%= form_for #survey do |f| %>
<% if #survey.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(#survey.errors.count, "error") %> prohibited this survey from being saved:</h2>
<ul>
<% #survey.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<br>
<%= f.fields_for :questions do |f| %>
<fieldset>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content %><br />
<% Food.all.each do |fd| %>
<fieldset>
<%= f.fields_for :answers do |f| %>
<%= f.text_field :name, :value => fd.name %>
<%= f.number_field :quantity %>
<% end %> <br>
</fieldset>
<% end %>
</fieldset>
<br>
<% end %>
<br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I'm trying to do is:
List all foods name and drinks name inside foods and drinks fieldset
Give each of the foods and drinks a quantity (this quantity column is inside answers table)
Save and update it
But I got no luck. When I'm try to load the edit view (the form), I managed to list all of the foods name. But, I've no idea how to list all of the drinks name in its own fieldset.
I try to make it like this but it didn't work:
<% if :content == "Foods" %>
<%= #loads foods %>
<% else %>
<%= #loads drinks %>
<% end %>
And, when I try to save the foods/drinks name and its quantity, it didn't work too.
Demo:
How to fix this problem?
Note:
This is update method inside surveys_controller:
def update
if #survey.update(survey_params)
redirect_to #survey, notice: "Successfully updated survey."
else
render :edit
end
end
...
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:id, :_destroy, :content, answers_attributes: [:id, :_destroy, :content, :quantity]])
end
Update:
This is my show.html.erb
<h1><%= #survey.name %></h1>
<ul class="questions">
<% #survey.questions.each do |question| %>
<li>
<%= question.content %>
<ol class="answers">
<% question.answers.each do |answer| %>
<li><%= answer.content %> (<%= answer.quantity %>)</li>
<% end %>
</ol>
</li> <br>
<% end %>
</ul>
<%= link_to 'Edit', edit_survey_path(#survey) %> |
<%= link_to 'Back to Surveys', surveys_path %>
You might be seeing an issue with variable scope. Each time you create a nested form with f.fields_for you pass in the variable f, even though f is the variable used in the parent.
Try calling it something different with questions and answers, such as:
<%= f.fields_for :questions do |fq| %>
<fieldset>
<%= fq.label :content, "Question" %><br />
<%= fq.text_area :content %><br />
<% Food.all.each do |fd| %>
<fieldset>
<%= fq.fields_for :answers do |fa| %>
<%= fa.text_field :name, :value => fd.name %>
<%= fa.number_field :quantity %>
<% end %> <br>
</fieldset>
<% end %>
</fieldset>
<br>
<% end %>

Showing and editing has_many objects in Rails

I'm trying to do something that I imagine to be very basic, but I'm very new to Rails and am not sure what sure what I'm doing wrong. I've gone through several tutorials and searched for an answer and can't find what the issue is. Would appreciate any help!
I've got Models set up so that Clients have many Projects which have many Milestones:
class Client < ActiveRecord::Base
has_many :projects, :dependent => :destroy
end
class Project < ActiveRecord::Base
belongs_to :client
has_many :milestones, :dependent => :destroy
end
class Milestone < ActiveRecord::Base
belongs_to :project
end
Routes are set up as follows:
resources :clients
resources :milestones
resources :projects do
resources :milestones
end
In projects/show.html.erb, I want to display each milestone associated with a project and also provide a form that adds new milestones on that same page. When I submit the form, it adds a new milestone (a new LI within UL.card-list), but none of the values show up. Here is the code for projects/show.html.erb:
<h2><%= #project.name %> Milestones</h2>
<ul class="card-list">
<% #project.milestones.each do |m| %>
<li>
<div class="card-header">
<%= m.date %>
</div>
<div class="card-body">
<h3 class="name"><%= m.name %></h3>
<p class="description"><%= m.description %></p>
</div>
</li>
<% end %>
<li>
<div class="card-header">
New Milestone
</div>
<div class="card-body">
<%= form_for [#project,Milestone.new] do |f| %>
<%= f.hidden_field(:project_id, value: #project.id) %>
<div class="field">
<%= f.label :milestone %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :date %>
<%= f.date_field :date %>
</div>
<div class="actions">
<%= f.submit "Add Milestone" %>
</div>
<% end %>
</div>
</li>
</ul>
Here are the parameters that are coming through the form:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"3D12GTH+IhwMMQDKsj2l+KXe7OBxmub3eejb3pbpWao=",
"milestone"=>{
"project_id"=>"1",
"name"=>"Test Milestone",
"description"=>"test descrip",
"date"=>"2015-06-26"
},
"commit"=>"Add Milestone",
"project_id"=>"1"
}
Milestones controller:
def create
#project = Project.find(params[:project_id])
#milestone = #project.milestones.create!(params[milestone_params])
redirect_to #project
end
private
def milestone_params
params.require(:milestone).permit(:name, :description, :completed, :date, :project_id)
end
Please let me know if there's any other info I can provide that would help. Thanks!
Since you need to support both (POST /milestones and POST /projects/:project_id/milestones) the project_id to the form:
<%= form_for [#project,Milestone.new] do |f| %>
...
<%= f.hidden_field(:project_id, value: #project_id) %>
...
<%- end -%>
Or if your resource is always nested than project_id available in the params in your controller so you can just pass it:
class MilestonesContoller < ApplicationController
def create
#milestone = Milestone.new(milestone_params)
# this part was originally omitted for brevity.
if #milestone.save
redirect_to #milestone.project
else
render :new
end
end
# don't trust params from the scary interwebs
def milestone_params
params.require(:milestone)
.permit(:project_id, :name, :description, :date)
end
end
NOTE that you actually need to integrate this code with the other actions in your controller. It is just a minimal example to show the relevant concepts. Not something which is meant as a complete copy-paste-done solution.
You can also reduce your routes file down to:
resources :clients
resources :milestones
resources :projects do
resources :milestones
end
Use the options for resources if you need to customize the routes.

Rails 4 -Nested Models and Simple Form partial

I am trying to make an app in Rails 4.
I have a projects, project questions and a project answers model.
my models
class Project
has_many :project_questions, dependent: :destroy#, through: :projects
accepts_nested_attributes_for :project_questions
end
class ProjectQuestions
belongs_to :project#, counter_cache: true
has_many :project_answers, dependent: :destroy
belongs_to :user
accepts_nested_attributes_for :project_answers
end
class ProjectAnswer
belongs_to :project_question#, counter_cache: true
belongs_to :user
end
routes.rb
resources :projects do
# patch '/toggle-draft', to 'projects#toggle_draft', as: 'toggle_draft'
resources :project_questions do
resources :project_answers
end
end
In my projects_controller, I have permitted params for project questions and answers as follows:
project_question_attributes: [:title, :content, :user_id, :project_id,
project_answer_attributes: [:answer, :project_question_id]],
These params are also permitted in the Project questions and project answers controllers.
In my projects view, I want to render a partial that I have made in my project_questions view folder.
projects/show
<%= link_to 'Ask a question', new_project_question_path %> <% end %>
<%= render 'project_questions/pqps' %>
In my project_questions partial which is called _pqps, I have;
<div class="containerfluid">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<% f.simple_fields_for :project_questions, #project.project_questions.build do |f| %>
<div class="categorytitle">
<%= f.title %>
</div>
<div class="generaltext">
<%= f.content %>
</div>
<%= render 'project_answers/show' %>
<span class="editproject"> <% if current_user.id == #project.creator_id %>
<%= link_to 'Answer this question', new_project_answer_path %>
<% end %>
</span>
<% end %>
</div>
</div>
</div>
When I try this, I get an error that says:
undefined local variable or method `f' for #<#:0x0000010a11ce60>
I thought I was defining f at the beginning of the opening line of the _pqps form.
I'm really struggling to get a grip with coding. Can anyone see what I've done wrong?
You use f.simple_fields_for in pqps, but f is not defined anywhere.
You have to define it using simple_form_for somewhere. I don't know exactly where – it depends on your own needs, but if, say, the whole form is inside _pqps:
<div class="containerfluid">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<%= simple_form_for #project do |f| %>
<% f.simple_fields_for :project_questions, #project.project_questions.build do |f| %>
# ...
<% end %>
<% end %>
</div>
</div>
</div>
If form "starts" outside "_pqps" partial, then you have to pass f as a local parameter:
<%= render 'project_questions/pqps', f: f %>
projects_controller
def show
#project_questions = #project.project_questions.build
end
View
<%= simple_form_for #project_questions do |f| %>
<%= f.input :title%>
<%= f.input :content %>
<%= f.button :submit %>
<% end %>

Setting a comment form on a post

I would like to set a comment form on a post in the "group message show" view.But I have an error message like,
NoMethodError at /group_messages/64
undefined method `group_message_group_message_comments_path' for #<#:0x007f9c0afa0b38>
Could you give me some advice?
☆show.html.erb(group_messages)
<h2>Add a comment</h2>
<%= form_for([#group_message, #group_message_comment]) do |f| %>
<% if #group_message_comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#group_message_comment.errors.count, "error") %> prohibited this group_message_comment from being saved:</h2>
<ul>
<% #group_message_comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %><%# do%>
</ul>
</div><!-- error_explanation-->
<% end %><%# if any?%>
<div class="field">
<%= f.label :member_id %><br />
<%= f.number_field :member_id %>
</div>
<div class="field">
<%= f.label :gmessage_id %><br />
<%= f.number_field :group_message_id %>
</div>
<div class="field">
<%= f.label :group_id %><br />
<%= f.number_field :group_id %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions" >
<%= f.submit "Comment"%>
</div>
<% end %><%# form_for>
☆group_messages_controller
def show
if !checklogin? then return end
#group_message = GroupMessage.find(params[:id])
#isme = me? #group_message
#group_message_comment = GroupMessageComment.new
#group_message_comment = GroupMessage.find(params[:id]).group_message_comments.build
respond_to do |format|
format.html # show.html.erb
format.json { render json: #group_message }
end
end
☆GroupMessage model
class GroupMessage < ActiveRecord::Base
attr_accessible :content, :member_id, :group_id
belongs_to :member
belongs_to :group
has_many :group_message_comments
end
☆GroupMessageComment model
class GroupMessageComment < ActiveRecord::Base
attr_accessible :content, :gmessage_id, :group_id, :member_id
belongs_to :member
belongs_to :group_message
end
☆routes.rb
MiniSNS::Application.routes.draw do
resources :group_message_comments
root :to => 'members#login'
match '/groups/join'
resources :group_messages
resources :groups do
resources :group_messages
end
match '/members/new'
resources :index
resources :groups
post 'groups/:id' => 'group#show'
post '/groups/new'
post '/index/index'
match '/members/login'
match '/members/logout'
match '/members/friend'
match 'members/show'
post 'messages/comment'
resources :comments
resources :messages
resources :friends
resources :members
That error message is due to the following line of code:
<%= form_for([#group_message, #group_message_comment]) do |f| %>
This is because you haven't set the correct routing for your models. Can you post your routes.rb too so that I can have a look?
I think you need nested routes, something like:
resources :group_messages do
resources :group_message_comment
end

how to pass the value to custom foreign key and make the foreign key appears its value in the second form

how can to pass the value to a custom foreign key (ward_id) and how to make the admission number which will be inserted in student form , appears in the second form parent/guardian detals > ward_id , i am having the following:
students_controller.rb
class StudentsController < ApplicationController
def index
#student = Student.all
end
def show
#student = Student.find(params[:id])
end
def new
#student = Student.new
end
def create
#student = Student.new(params[:student])
if #student.save
flash[:success] = ' Student Record Saved Successfully. Please fill the Parent Details.'
redirect_to new_guardian_url
else
flash.now[:error] = 'An error occurred please try again!'
render 'new'
end
end
def edit
end
end
student.rb
class Student < ActiveRecord::Base
attr_accessible :address_line1, :address_line2, :admission_date, :admission_no, :birth_place, :blood_group, :city,
:class_roll_no, :date_of_birth, :email, :first_name, :gender, :language, :last_name, :middle_name,
:phone1, :phone2, :post_code, :religion, :country_id, :nationality_id
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :batch
belongs_to :nationality , class_name: 'Country'
has_many :guardians , foreign_key: 'ward_id'
has_many :student_previous_subject_marks
has_one :student_previous_data
end
guardians_controller.rb
class GuardiansController < ApplicationController
def index
end
def show
end
def new
#guardian = Guardian.new
end
def edit
end
end
guardian.rb
class Guardian < ActiveRecord::Base
attr_accessible :city, :dob, :education, :email, :first_name, :income, :last_name, :mobile_phone, :occupation,
:office_address_line1, :office_address_line2, :office_phone1, :office_phone2, :relation
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :ward , class_name: 'Student'
end
routes.rb
Triton::Application.routes.draw do
get "guardians/index"
get "guardians/show"
get "guardians/edit"
get "students/index"
get "students/show"
get "students/edit"
resources :articles do
resources :comments
end
resources :users
resources :guardians
resources :students
resources :sessions
get '/user/dashboard', to: 'static_pages#home'
get '/student/admission1' , to: 'students#new'
get '/student/admission2' , to: 'guardians#new'
root to: 'sessions#new'
end
students/new.html.erb
<h1>Admission</h1>
<h4>Step 1 - Student details</h4>
<div>
<div class="span6 offset2">
<%= form_for(#student) do |f| %>
<% if #student.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#student.errors.count, 'error') %>
</div>
<ul>
<% #student.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :admission_no %></div></th>
<th><div class="field"><%= f.text_field :admission_no %></div></th>
</tr>
<tr>
<th><div class="field"><%= f.label :admission_date %></div></th>
<th><div class="field"><%= f.text_field :admission_date , :class => 'datepicker'%></div></th>
</tr></table>
<h4>Student - Personal Details</h4>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :first_name %></div></th>
<th><div class="field"><%= f.text_field :first_name %></div></th>
</tr>
<tr>
guardians/new.html.erb
<h1>Admission</h1>
<h4>Step 2 - Parent details</h4>
<div class="row-fluid">
<div class="span4 offset1 hero-unit">
<%= form_for #guardian do |f| %>
<% if #guardian.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#guardian.errors.count, 'error') %>
</div>
<ul>
<% #guardian.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<div class="field">
<%= f.label 'Student Admission number' %>
<%= f.text_field :ward_id , disabled: true %>
</div>
<h4>Parent - Personal Details</h4>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
//not the whole file, just copied what is needed to be seen

Resources