RoR Error: undefined method students_index_path - ruby-on-rails

I have been getting this error and have been unable to fix it
(the post at StackOverflow Undefined Method Index Path didn't fix my problem).
This exact error message I am getting is (I am using Rails 3.0.5 and Ruby 1.9.2):
NoMethodError in Students#new
Showing C:/rails/ww/app/views/students/_form.html.erb where line #1 raised:
undefined method `students_index_path' for #<#:0x4991c10>
Here are the files:
students_controller.rb
class StudentsController < ApplicationController
def new
#students = Students.new
end
end
new.html.erb
<h1>Enroll New Student</h1>
<%= render 'form' %>
<%= link_to 'Back', students_path %>
_form.html.erb
<%= form_for(#students) do |f| %>
<% if #students .errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#students .errors.count, "error") %> prohibited this course from being saved:</h2>
<ul>
<% #students .errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :pen %><br />
<%= f.text_field :pen %>
</div>
<div class="field">
<%= f.label :fName %><br />
<%= f.text_field :fName %>
</div>
<div class="field">
<%= f.label :lName %><br />
<%= f.text_field :lName %>
</div>
<div class="field">
<%= f.label :pass %><br />
<%= f.text_field :pass %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Thanks for the answer in advanced.

It should be <%= form_for(#student) do |f| %> not #students

Why your model name is plural ? It should be singular.
Just rename or drop/create your model with name Student.
Add resources :students to config/routes.rb
In controller, #student = Student.new
Thats it.. should work with this...

This is because you are passing in the variable #students into form_for, so rails interprets that as students_index_path. If you were to pass in a variable named #student, you'd fine. (assuming you created a variable #student = Student.new)
I'd read up on how form_for interprets it's arguments here.

Just add string in routes.rb
resources :students
instead
match "/students/:id" => "students#new"
or whatever you have (:

Related

Weird redirection when updating datas

I generated a scaffold for a portfolio via the Rails command, rails g portfolio titre:string, thumbnail:string lien:string description:text. I also added FriendlyId to get a better URL, and that's about all. Here is the 'update' action.
def update
if #portfolio.update(portfolio_params)
redirect_to #portfolio, notice: 'Portfolio mis à jour.'
else
render :edit
end
end
However, when trying to update a project in my portfolio, the submit button tries to get to 'portfolio#update' via patch, but puts a '.' instead of a '/' which gives me No route matches [PATCH] "/portfolios.test-1"
For the route, I only have resources :portfolios
edit : added the form
<%= form_for #portfolio, url: portfolios_path(#portfolio) do |f| %>
<% if portfolio.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(portfolio.errors.count, "error") %> prohibited this portfolio from being saved:</h2>
<ul>
<% portfolio.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :titre %>
<%= f.text_field :titre %>
</div>
<div class="field">
<%= f.label :categorie %>
<%= f.text_field :categorie %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :thumbnail %>
<%= f.file_field :thumbnail %>
</div>
<div class="field">
<%= f.label :lien %>
<%= f.text_field :lien %>
</div>
<div class="actions">
<%= f.submit 'Enregistrer' %>
</div>
<% end %>
I didn't have any other possibilities that doing #portfolio, url: portfolios_path(#portfolio), otherwise Rails considered that '#portfolio' was nil
edit 2 : added the private 'set_portfolio' params
private
# Use callbacks to share common setup or constraints between actions.
def set_portfolio
#portfolio = Portfolio.friendly.find(params[:id])
end
What's wrong with my app ?
portfolios_path is the collection path.
change it portfolio_path should fix it.
<%= form_for #portfolio, url: portfolio_path(#portfolio) do |f| %>
I guess you are going to use this form for creating new portfolio as well, so change it to <%= form_for(#portfolio) %> should fix it and will also work for both cases. form_for will submit to correct path.

Rails - Couldn't find Student with 'id'=

I'm getting the error above when I try to create a a 'mark' for a 'student'. I can't figure out how to pass the :student_id when I create a new mark.
Routes
Rails.application.routes.draw do
resources :students do
resources :marks
end
resources :marks
root 'students#index'
Marks Controller
class MarksController < ApplicationController
def create
#student = Student.find(params[:student_id])
#mark = #student.marks.create(params[:input1, :input2, :input3, :weight1, :weight2, :weight3, :mark1, :mark2, :mark3, :final_mark].permit(:input1, :input2, :input3, :weight1, :weight2, :weight3, :mark1, :mark2, :mark3, :final_mark))
#mark.save
if #mark.save
redirect_to student_path(#student)
else
render 'new'
end
end
def new
#mark = Mark.new
end
private
def set_mark
#mark = Mark.find(params[:id])
end
end
Students Show View
<p id="notice"><%= notice %></p>
<p>
<strong>Student Number</strong>
<%= #student.StudentNumber %>
</p>
<p>
<strong>Project Title</strong>
<%= #student.ProjectTitle %>
</p>
<p>
<strong>Project PDF</strong>
<%= #student.ProjectTitle %>
</p>
<p>
<strong>Reader 1</strong>
<%= #student.Reader1 %>
</p>
<p>
<strong>Reader 2</strong>
<%= #student.Reader2 %>
</p>
<h3> <%= link_to 'Add Mark', new_student_mark_path(#student), class:"btn btn-warning"%> </h3>
<p>
<strong>Reader 3</strong>
<%= #student.Reader3 %>
</p>
<%= link_to 'Edit', edit_student_path(#student) %> |
<%= link_to 'Back', students_path %>
Marks Form
<%= form_for #mark, html: {multipart: true} do |f| %>
<% if #mark.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#mark.errors.count, "error") %> prohibited this grading from being saved:</h2>
<ul>
<% #mark.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label 'Introduction' %><br>
<%= f.text_area :input1 %>
<%= f.number_field :weight1 %>
<%= f.number_field :mark1 %>
</div>
<div class="field">
<%= f.label 'Main' %><br>
<%= f.text_area :input2 %>
<%= f.number_field :weight2 %>
<%= f.number_field :mark2 %>
</div>
<div class="field">
<%= f.label 'Conclusion' %><br>
<%= f.text_area :input3 %>
<%= f.number_field :weight3 %>
<%= f.number_field :mark3 %>
</div>
<div class="actions">
<%= f.submit class:"btn-xs btn-success"%>
</div>
<% end %>
Mark model
class Mark < ActiveRecord::Base
belongs_to :student
end
Student Model
class Student < ActiveRecord::Base
has_many :marks
has_attached_file :document
validates_attachment :document, :content_type => { :content_type => %w(application/pdf) }
end
It's probably something really stupid but if anyone could explain the problem I'd be really grateful.
Thanks
I don't suggest you using hidden fields for this purpose.
You should pass student together with mark into form_for helper and rails will generate proper url for you which will look like: /students/:student_id/marks
In this case it will be possible to extract student_id from params in your action later.
form_for [#student, #mark], html: {multipart: true} do |f|
More information about nested resources:
http://guides.rubyonrails.org/routing.html#nested-resources
http://www.informit.com/articles/article.aspx?p=1671632&seqNum=7
https://gist.github.com/jhjguxin/3074080
UPDATE:
Forgot to mention that in order to make this work you need to pass student instance into your template at new action:
def new
#student = Student.find(params[:student_id])
#mark = #student.marks.build
end

Nested routes form_for partial not working for new and edit actions - Rails 4

I used the generator to scaffold categories and questions.
my routes.rb
resources :categories do
resources :questions do
resources :choices, only: [:index]
end
end
my problem occurs when i try to add or edit a question.
here is my partial form, before you ask the relationship works ok.
<%= form_for [#question.category, #question] do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :question_type %><br>
<%= f.text_field :question_type %>
</div>
<div class="field">
<%= f.label :explanation %><br>
<%= f.text_field :explanation %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :category_id %><br>
<%= f.text_field :category_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
what must i change for it to work? for now i get,
undefined method `questions_path'
Try this
UPDATE
Controller
#category = Category.find(params[:category_id])
#question = #category.questions.new
_form
<%= form_for([#category, #question]) do |f| %>
Reference
You should pass parent and then build child for same for new object.
<%= form_for [#category, #category.questions.build] do |f| %>
To edit:
<%= form_for [#category, #category.questions.first_or_your_object] do |f| %>
Like this :
<% if #category.new_record? %>
<%= form_for [#category, #category.questions.build] do |f| %>
<% else %>
<%= form_for [#category, #category.questions.first_or_your_object] do |f|
<% else %>
Also add in your category model:
accepts_nested_attributes_for :questions
Add this line to your category.rb model file:
accepts_nested_attributes_for :questions
Also, in your controller:
#category = Category.find(params[:category_id])
#question = Question.new(category: #category)
and form:
<%= form_for([#category, #question]) do |f| %>

undefined method `model_name', Rails

I am trying to implement simple form in home#index page using:
<%= render "forms/form"%>
Form look like this:
<%= form_for(#form) do |f| %>
<% if #form.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#form.errors.count, "error") %> prohibited this form from being saved:</h2>
<ul>
<% #form.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :defect %><br />
<%= f.text_field :defect %>
</div>
<div class="field">
<%= f.label :region %><br />
<%= f.text_field :region %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
But when I access that page, I got this error message:
undefined method `model_name' for NilClass:Class
First of all I though it is because my model name is also Form, but then I checked Rails 3 reserved words, but there wasn't "form" !
Thanks in advance!
In home controller, set the instance variable #form in the index action as:-
def index
#form = Form.new
end
Your #form instance variable's value is nil. You should set it in controller.

Ruby on Rails, instead of update make new entry to model

I made a simple demo site, with an model for the patients name (name:string) and another model with the treatment (content:text). I created this "project" to learn more about the accepts_nested_attribute for tag and the fields_for tag.
Now my problem is that on the patient show page i created an nested formula for the treatment , like you can see here:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #patient.name %>
</p>
<ol>
<% for treatment in #patient.treatments %>
<li><%= treatment.content %></li>
<% end %>
</ol>
<%= form_for(#patient) do |f| %>
<%= f.fields_for :treatments do |builder| %>
<div class="field">
<%= builder.label :content %><br />
<%= builder.text_field :content %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit', edit_patient_path(#patient) %> |
<%= link_to 'Back', patients_path %>
So my problem is that in the builder.text_field :content better called the input shows up the last saved treatment from <%= builder.content %>, but i want that he does not update it instead i want to add new treatments! Hopefully somebody understands me! Thanks
I would create separate controller for creating only the treatment, eg.
# treatments_controller.rb
class TreatmentsController < ApplicationController
def create
#patient = Patient.find(params[:patient_id])
#treatment = #patient.treatments.new(params[:treatment])
if #treatment.save
redirect_to #patient
else
# handle unsuccessful treatment save
end
end
end
# routes.rb:
resources :patients do
resources :treatments, only: :create
end
# form:
<%= form_for #patient, #treatment do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should also set #treatment variable in the patient#show action, like this:
#treatment = #patient.treatments.new

Resources