I'm new to rails and trying to create a new page with a form, fairly simple, but it keeps coming back with this error (listed below) on the <%= form_for #whiteboard do |f| %>line. I've looked at similar posts where people are having the same issue as me but none of the solutions seem to work for me. Would greatly appreciate some help, thanks!
Error Message:
NoMethodError in Whiteboard#new
undefined method `whiteboards_path' for #<#<Class:0x37014d8>:0x36b2d10>
Did you mean? whiteboard_path
<%= form_for #whiteboard do |f| %>
<div>
<% f.label :title %>
<% f.text_field :title %>
</div>
My Controller:
class WhiteboardController < ApplicationController
def index
#whiteboards = Whiteboard.all;
end
def show
#whiteboard = Whiteboard.find(params[:id])
end
def new
#whiteboard = Whiteboard.new
end
end
My View (whiteboard/new.html.erb):
<%= form_for #whiteboard do |f| %>
<div>
<% f.label :title %>
<% f.text_field :title %>
</div>
<div>
<% f.label :description %>
<% f.text_field :description %>
</div>
<div>
<% f.submit :title %>
</div>
<% end %>
My routes:
Rails.application.routes.draw do
root to: 'home#index'
resources :whiteboard
get 'whiteboard/wbpage'
get 'home/index'
get 'home/info'
devise_for :users
end
This is a simple pluralization error.
resources :whiteboards
In Rails resources should always be plural. On the rare occasion that you have a real singular resource you should use resource instead.
My Suggestion please mind it
when you create controller use pluralization
when you create Model use Singular (first letter must be camel case)
For Example
rails g controller articles
rails g model Article
Related
I'm new to RoR. Wanted to try if my next web app should be RoR based. Started out following this trail: https://guides.rubyonrails.org/getting_started.html. Worked like a charm in the beginning, but i'm unable to get the darn thing to create new records. Any hint as to what i'm missing is appreciated.
The error i'm getting is this:
D, [2020-12-18T09:59:56.917197 #132399] DEBUG -- : Createevent
F, [2020-12-18T09:59:56.917893 #132399] FATAL -- :
ActionController::ParameterMissing (param is missing or the value is empty: Event):
app/controllers/event_controller.rb:33:in `event_params'
My routing looks like this:
Rails.application.routes.draw do
post 'event/new', to: 'event#create'
resources :event
end
(I'm baffled by the need for specifying the POST above, but without it the create is never fired. ).
The eventcontroller looks like this:
class EventController < ApplicationController
def index
#events = Event.all
end
def show
#event = Event.find(params[:id])
end
def new
logger = Rails.logger
logger.info 'NewEvent'
#event = Event.new
end
def create
logger = Rails.logger
logger.debug 'Createevent'
#event = Event.new(event_params)
logger.debug 'Eventcreated'
if #event.save
redirect_to event_path
else
render :new
end
end
private
def event_params
params.require(:Event).permit(:EventName, :Description, :EventStart, :EventEnd, :Maxparticipants, :Waitlist )
end
end
Index and show works fine.
The new.html.erb looks like this:
<h1>New Event</h1>
dsfsdfds
<%= form_with model: #Event do |form| %>
<div>
<%= form.label :eventname %><br>
<%= form.text_field :EventName %>
<%= #event.errors.full_messages_for(:EventName).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :Description %><br>
<%= form.text_field :Description %>
<%= #event.errors.full_messages_for(:description).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :EventStart %><br>
<%= form.text_field :EventStart %>
<%= #event.errors.full_messages_for(:eventstart).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :Eventend %><br>
<%= form.text_field :Eventend %>
<%= #event.errors.full_messages_for(:eventend).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :Maxparticipants %><br>
<%= form.text_field :Maxparticipants %>
<%= #event.errors.full_messages_for(:Maxparticipants).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.label :Waitlist %><br>
<%= form.text_field :Waitlist %>
<%= #event.errors.full_messages_for(:waitlist).each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<div>
<%= form.submit %>
</div>
<%= submit_tag "Create" %>
<% end %>
Routes:
Prefix Verb URI Pattern Controller#Action
event_new POST /event/new(.:format) event#create
event_index GET /event(.:format) event#index
POST /event(.:format) event#create
new_event GET /event/new(.:format) event#new
edit_event GET /event/:id/edit(.:format) event#edit
event GET /event/:id(.:format) event#show
PATCH /event/:id(.:format) event#update
PUT /event/:id(.:format) event#update
DELETE /event/:id(.:format) event#destroy
Things created using:
bin/rails generate model Event EventName:string Description:string EventStart:datetime EventEnd:datetime Maxparticipants:integer WaitList:integer
bin/rails generate controller Event index
Version:
About your application's environment
Rails version 6.0.3.4
Ruby version ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
RubyGems version 3.1.4
Rack version 2.2.3
Thanks to Hackman & nathanvda for clarifying. I scratched everything and started over and i finally got it working. Still way too much woodo and black magic for my taste though. The error message part got me baffled for three consecutive hours.
As stated i followed the guide and therefore ended up using (in new)
<%= form_with model: #event do |form| %>
<% if #event.errors.any? %>
<h2>Errors</h2>
<ul>
<% #event.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
...
Which works (well, sort of). The record gets saved if ok, the validations rules gets fired
class Event < ApplicationRecord
validates :eventname, presence: true
validates :description, presence: true, length: { minimum: 20 }
end
and if violated no record gets written to the database, but no error messages either. Nil. Nothing. After poking around on the internet i ended up changing to
<%= form_for #event do |form| %>
and then error reporting works. Only problem with this solution is that the use of form_for is discouraged as it is being rendered obsolete.
Final version ended up being:
<%= form_with model: #event, local: true do |form| %>
Which does the trick.
Next step in my evaluation will be the use of natural keys as the use of surrogate keys is not an option for some of the data structures needed in this project. (during my poking around i got the impression that natural keys are some kind of a sore tooth in RoR, but time will show.
To start out, your resources in the routes should be pluralized. So resources :event should be resources :events
Also the controller name should be pluralized. So EventController would become EventsController.
Now the needed routes should work fine and you can get rid of the specified POST in your routes.rb
Now inside your controller you have the event_params method. There it is preferred to downcase/snake_case the names like this:
def event_params
params.require(:event).permit(:event_name #etc)
end
If your column names in DB are EventName etc, I would advice to rename them.
Last thing: In your form you got #Event with uppercase while in the controller#new action you defined #event with lowercase. Use lowercase everywhere.
So if you had started as follows:
bin/rails generate model Event event_name:string description:string event\-start:datetime event_end:datetime max_participants:integer wait_list:integer
bin/rails generate controller events index
Then the generated code would work a lot better.
A few tips to clarify:
in ruby we only write classes with a capital, for variables we use snake case (everything lowercase and words connected with underscores). So by extension when generating a model all attributes should be snake cased
a controller in general uses the plural form, since it "controls" all the events (not just one).
I decided to start a Ruby on Rails project without scaffolding because I actually wanted to learn in the process. I have searched this site but cannot seem to find the answer to my question so I will ask here. I started a Rails project where the user enters their grades. Unfortunately, on the new grade page when the user hits Create Grade I get the error in the subject line. Here is my code for the form that I use in the new page under the grade controller.
<%= form_with(model: grade, local: true) do |f| %>
<% if grade.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(grade.errors.count, "error") %> prohibited this grade
from being saved:</h2>
<ul>
<% grade.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :assignment %>
<%= f.text_field :assignment %>
</div>
<div class="field">
<%= f.label :score %>
<%= f.text_field :score %>
<div class="actions">
<%= f.submit %>
</div>
This is my routes page:
Rails.application.routes.draw do
resources :grades
root 'grade#index'
get 'grade/index'
get 'grade/show'
get 'grade/new'
get 'grade/edit'
get 'grade/create'
get 'grade/update'
get 'grade/destroy'
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
If more code is needed to answer the question please let me know.
Based on the title of your question, Rails is looking for a file called app/controllers/grades_controller.rb file that defines the GradesController class.
Create the following file, and you should get to the next step
# app/controllers/grades_controller.rb
class GradesController < ApplicationController
def new
#grade = Grade.new
end
def create
# logic for persisting the grade object goes here
end
# other controller methods, here
end
In the form for a new grade, use the instance variable (the one with the # symbol) you defined in the GradesController#new method:
<%= form_with(model: #grade, local: true) do |f| %>
In your routes, this is all you should need:
Rails.application.routes.draw do
resources :grades
root 'grades#index' # not 'grade#index'
end
Controllers are plural, check the name of the controller file to ensure it's plural then check the controller class name change both from GradeController to GradesController.
I'm a real newbie at Ruby and Rails, and I've been looking for the solution for two days. I need to submit data from form_tag to action 'create' in my controller to add new entries to database, but looks like I'm doing something terribly wrong, because absolutely nothing happens, and it seems that form_tag doesn't even redirect to needed action.
Here's the page code:
<h1>Todos</h1>
<% #projects.each do |project| %>
<tr>
<h2><%= project.title %></h2>
<% project.todos.each do |todo| %>
<ul style="list-style-type:disc">
<li><%= todo.text %></li>
</ul>
<% end %>
</tr>
<% end %>
<%= form_tag({controller: "mega", action: "create"}, method: "get", remote: true) do %>
<h2>New todo</h2>
<p>
<%= text_field_tag 'text' %>
</p>
<p>
<%= select_tag 'title', options_from_collection_for_select(#projects, 'id', 'title') %>
</p>
<p>
<%= link_to 'CANCEL' %>
<%= link_to 'OK', "", :onclick => "$('#form_id').submit()" %>
</p>
<% end %>
And the controller:
class MegaController < ApplicationController
def index
#projects = Project.all
#todos = Todo.all
end
def update
end
def create
#newTodo = Todo.create(text: params[:text])
#newProject = Project.find_by(title: params[:title])
#newProject.todos << #todo
#newTodo.save
end
end
My routes file. I seriously don't know how it works:
Rails.application.routes.draw do
get 'mega/index'
root 'mega#index'
get 'mega/update'
post 'mega/create'
resources :todos
resources :projects
end
You create resources with a POST request. Never GET.
GET requests should be idempotent - they should not update or alter resources on the server. One very important reason is that they are stored in the browser's history, so pressing the back button will cause unintended consequences for the user.
In Rails flavor MVC instead of tacking the action name on the path of the route you use the HTTP verb to create routes to the correct action:
GET /things things#index
POST /things things#create
I'm not going to attempt to salvage your code (it's deeply flawed) and instead show you how you would solve this the rails way as it is much simpler:
<%= form_for(Todo.new) do |f| %>
<h2>New todo</h2>
<%= f.text_field :text %>
<%= f.collection_select(:project_id, #projects, :id, :title, prompt: true) %>
<%= f.submit %>
<% end %>
This would submit to todos#create - if you want to route it to an unconventional action you can use the url option:
<%= form_for(Todo.new, url: polymorphic_path(controller: 'foo', action: 'bar')) do |f| %>
It's best to learn the rules before you break them.
I am building a Project management with the following associations:
Project
- Section
- Milestone
- Issue
Inside app/views/section/show.html.erb - I want to have the entire section's milestones and its related issues. For each milestone I want to have a different form to create a new associated issue.
This is how the view file looks like:
<%= #section.title %>
<% #milestones.each do |milestone| %>
<div id="milestone">
<%= milestone.info %>
</div>
<% milestone.issues.each do |issue| %>
<div id="issue">
<p><%= issue.content %></p>
</div>
<% end %>
At the end of each milestone I have the following form to add a new issue:
<%= form_for([#project, milestone.issues.build], :url => project_section_milestone_issue_path ) do |f| %>
<p>
<%= f.text_field :content %>
<%= f.submit %>
</p>
<% end %>
This is my routes.rb:
resources :projects do
resources :sections do
resources :milestones do
resources :issues
end
end
end
The form doesn't work, the page (view file) itself doesn't load and errors with wrong path url. I'm guessing something is wrong either with the routes or with the assignment within the form_for method.
The problem was with the form_for statement.
With #Zippie's hint, I changed it to: <%= form_for([#project, #section, milestone, milestone.issues.build] ) do |f| %> and it fixed the problem.
Usually I just use something similar to
http://railscasts.com/episodes/196-nested-model-form-part-1
Now i have an existing User which i am trying to add new cars and annimals. The User has_many cars and annimals and accepts_nested_attributes_for cars and annimals
If i do
= form_for(#user) do |f|
= f.fields_for #user.cars.build do |c|
I get error:
unknown attribute: car
And if i do
= form_for(#user) do |f|
= f.fields_for :cars do |c|
I get a list of all existing cars for that user (when I want to make a new one)
Thannks!
ps: i guess i should add, i'm using simple_form_for and simple_fields_for, it might be a bug with that...
Deep inside the rails api I found:
It’s also possible to specify the instance to be used:
<%= form_for #person do |person_form| %>
...
<% #person.projects.each do |project| %>
<% if project.active? %>
<%= person_form.fields_for :projects, project do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
<% end %>
<% end %>
So in my case, i guess the syntax would be
= form_for(#user) do |f|
= f.fields_for :cars, #user.cars.build do |c|