I'm facing this error for quite some time now, I've tried a lot of solutions but none is working. Making my scenario clear :
1) I'm not using scaffold command & creating the whole thing manually
2) The error is generated on trying to create a new Charity
ERROR:
Showing /home/hitesh/Rails/ReachOut/app/views/charity/_form.html.erb where line #1 raised:
undefined method `charities_path' for #<#<Class:0x000000035ab3f8>:0x0000000344f220>
Extracted source (around line #1):
1: <%= form_for(#charity) do |f| %>
2: <% if #charity.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#charity.errors.count, "error") %> THis is where i screwed prohibited this charity from being saved:</h2>
MY _form.html.erb LOOKS LIKE THIS :
<%= form_for(#charity) do |f| %>
<% if #charity.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#charity.errors.count, "error") %> THis is where i screwed prohibited this charity from being saved:</h2>
<ul>
<% #charity.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>
MY routes.rb contains the entry for a charity
ReachOut::Application.routes.draw do
resources :charity
# The priority is based upon order of creation:
# first created -> highest priority.
My CharityController :
class CharityController < ApplicationController
# GET /charity/new
# GET /charity/new.json
def new
#charity = Charity.new
respond_to do |format|
format.html #new.html.erb
format.json { render json: #charity}
end
end
and My charity.rb (MODEL) : does contain a charity class
...
Guys I;ve tried a lot of things (changing # => :) but still m not able to remove this error ... Hope anyone of you can help me in it... I searched for charities_path in my whole system and could find nothing :) :(.
you need resources :charities in routes.rb
And controller must be named as CharitiesController
Or you must manually set path helper method, but in this case you can face another problems, better follow rails naming rules
Related
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 am fairly new to rails and I am trying to the shopping cart html view to the site admin when a order is made. The email portion is working just fine with simple html but when I add the ruby code to render the views page I get the following error:
NoMethodError in Charges#create
Showing /home/ubuntu/workspace/app/views/order_mailer/order_email.html.erb where line #7 raised:
undefined method `size' for nil:NilClass
Extracted source (around line #7):
5
6
7
<%= render "carts/shopping_cart", size: #order_items.size %>
Rails.root: /home/ubuntu/workspace
Application Trace | Framework Trace | Full Trace
app/views/order_mailer/order_email.html.erb:7:in `_app_views_order_mailer_order_email_html_erb___1590505826361550286_70123907983000'
app/mailers/order_mailer.rb:11:in `order_email'
app/controllers/charges_controller.rb:10:in `create'
From what I have read I think I need to add locals to my render code but I am confused on what exactly locals are and what they would be in my code. If I am completely off track and this error has nothing to do with locals I would appreciate some guidance in the right direction.
Thanks!
order_email view:
<h1>You have a new order </h1>
<%= render "carts/shopping_cart", size: #order_items.size %>
The view I am trying to render in the email:
<% if !#order_item.nil? && #order_item.errors.any? %>
<div class="alert alert-danger">
<ul>
<% #order_item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if #order_items.size == 0 %>
<p class="text-center">
There are no items in your shopping cart. Please <%= link_to "go back", root_path %> and add some items to your cart.
</p>
<% else %>
<% #order_items.each do |order_item| %>
<%= render 'carts/cart_row', product: order_item.product, order_item: order_item, show_total: true %>
<% end %>
order_mailer.rb:
class OrderMailer < ApplicationMailer
default from: "xxxx#gmail.com"
def order_email(order_items)
#order_items = order_items
mail(to: "xxxx#gmail.com", subject: "Your subject")
end
end
I believe locals are only used when doing a render partial, which you should be able to do for this but you'd need to make a few adjustments.
Each of the partials' filename need to be adjusted to have and underscore in front of them, but you still reference them without the underscore (I know it's a bit confusing).
So rename carts/shopping_cart to carts/_shopping_cart
and then change where it's referenced to:
<%= render partial: "carts/shopping_cart", locals:{size: #order_items.size} %>
Do the same sort of thing with 'carts/cart_row'
I have a multi-model form and I cannot seem to capture the errors related to the nested models. This is the hierarchy of the form Project->Team->Roles->Role_skill_relationship. I am able to capture errors related the project model instance #project but I have been unsuccessful at capturing validations related to the Role and Skills models. The errors are directly returned in the browser page rather than redirecting and flashing to the screen. One example of an error if I intentionally fill out a role portion of the form incorrectly is
NoMethodError in Roles#create
Showing
C:/Users/Dstile/Documents/GitHub/creunity_app/app/views/skills/_form.html.erb
where line #8 raised:
undefined method `map' for nil:NilClass Extracted source (around line #8)
7: <%= skill_form.label :skill %>
8: <%= skill_form.collection_select :skill_id, #skills, :id, :name, :prompt => "Select a > skill" %>
Here is a portion of the code
<%= render 'shared/project_error_messages' %>
<%= project_form.label :title %>
<%= project_form.text_field :title %>
<%= project_form.label :category, "Category" %>
<%= project_form.select(:category, Project::CATEGORY_TYPES) %>
<%= project_form.label :description %>
<%= project_form.text_area :description %>
<%= project_form.label :goal_1, "Goal 1:" %>
<%= project_form.text_field :goal_1 %>
<h2>Your Team</h2>
<%= project_form.fields_for :team do |f| %>
<%= render 'teams/form', :team_form => f %>
<% end %>`
Here is the error render code
'<% if #project.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#project.errors.count, "error") %>.
</div>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>'
The role form is nested within the team form in the same manner team is nested in project. From all of the other threads I have read my understanding is that the errors for project and all of its children models (team, roles, role_skill_relationships) should be captured by the #parent object.
Is there a config setting or piece of code I am missing that should force the browser to ignore the errors? My thinking is that the errors may be in #project but that this process is interrupted.
It appears #skills has not been set. #collection_select runs #map on the passed-in collection (#skills in this case), and will show that error if the collection is nil (which is the default value for undefined instance variables).
Remember that, in the case of validation errors, the #create method in your controller will simply be rendering a template - it does not run the corresponding action method for that template. So if you're defining #skills in your #new action, then you need to also define it in your #create action (or, better yet, in a before_filter).
My simple form is not doing a POST. I've been looking at this and haven't been able to see what is wrong (I'm sure it's in my routes). Here's what I have:
view:
views/buyers/new.html.erb
<%= form_for(#buyer) do |f| %>
<%= f.text_field :phone %><br />
<%= f.text_field :make %><br />
<%= f.text_field :model %><br />
<%= f.submit %>
<% end %>
controller:
BuyersController
def new
#title = "Welcome to Car Finder"
#buyer = Buyer.new
end
def create
#buyer = Buyer.new(params[:buyer])
if #buyer.save!
redirect_to success
else
redirect_to :back
end
end
routes:
resources :buyers
rake routes:
buyers GET /buyers(.:format) buyers#index
POST /buyers(.:format) buyers#create
new_buyer GET /buyers/new(.:format) buyers#new
edit_buyer GET /buyers/:id/edit(.:format) buyers#edit
buyer GET /buyers/:id(.:format) buyers#show
PUT /buyers/:id(.:format) buyers#update
DELETE /buyers/:id(.:format) buyers#destroy
When I submit the form, it stays on the same page, never going to the create action. Below is from the log
Started GET "/?..[params]..."
Processing by BuyersController#new as HTML
Thanks for any help you can give
It is probably wise to restart your server. You're issue may lie in validations you have at your persistence level or in your buyer.rb file. Add this to the _form.html.erb:
<% if #buyer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#buyer.errors.count, "error") %> prohibited this from being saved: </h2>
<ul>
<% #buyer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Try to complete the request again. See if any errors are being thrown. Fix those.
Rails 3.0 deprecated f.error_messages and now requires a plugin to work correctly - I however want to learn how to display error messages the (new) native way. I am following the getting started guide, which uses the deprecated method when implementing the comments form. For example:
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<% f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here is the correct way to do it (as generated by the scaffold):
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
. . .
I understand that I use the #post variable in the latter example, but what variable do I reference in the former to get the error messages for comment creation?
The best and clean way to implement error_messages in your form is by implementing error_messages in a FormBuilder.
For example, here is the error_messages method I've implemented for my last project.
By implemeting your own FormBuilder you can follow the rules and styles of your webdesigner...
Here is an example that will output the errors list in ul/li's with some custom styles :
class StandardBuilder < ActionView::Helpers::FormBuilder
def error_messages
return unless object.respond_to?(:errors) && object.errors.any?
errors_list = ""
errors_list << #template.content_tag(:span, "There are errors!", :class => "title-error")
errors_list << object.errors.full_messages.map { |message| #template.content_tag(:li, message) }.join("\n")
#template.content_tag(:ul, errors_list.html_safe, :class => "error-recap round-border")
end
end
Then in my forms :
= f.error_messages
And that's all.
I'm pretty sure all you'd need to do is reference #post.comments
So you could do something like:
<% #post.comments.each do |comment| %>
<% if comment.errors.any? %>
<% comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<% end %>
<% end %>
Or just pull all the errors out out:
comment_errors = #post.comments.map(&:errors)
and then loop through them in your display logic to output each of the comment errors.
This functionality exists as a standalone gem dynamic_form.
Add the the following to your Gemfile
gem 'dynamic_form'
From the github page:
DynamicForm holds a few helpers method to help you deal with your Rails3 models, they are:
input(record, method, options = {})
form(record, options = {})
error_message_on(object, method, options={})
error_messages_for(record, options={})
It also adds f.error_messages and f.error_message_on to your form builders.
Here is my solution to the whole error scene.
I created a partial which simply uses a model variable which one would pass when rendering it:
<%# app/views/errors/_error.html.erb %>
<%= content_for :message do %>
<% if model.errors.any? %>
<ul>
<% model.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<% end %>
You can easily add dynamic html class and/or id names based on the name of the model, as well as generic ones.
I have things setup where my error messages render in all the same place in a layout file:
<%# app/views/layouts/application.html.erb %>
<%= yield :message %>
If one didn't want that functionality, removing the content_for in the partial would do the trick.
Then in really any view you want you can simply write:
<%= render 'errors/error', model: #some_model %>
One could further expand this by creating a partial which takes a collection and leverages the error partial above:
<%# app/views/errors/_collection.html.erb %>
<% collection.each do |model| %>
<%= render 'errors/error', model: model %>
<% end %>
Render it with:
<%= render 'errors/collection', collection: #some_model.some_has_many_association %>
I like this way. It is simple, easy to manage/maintain, and incredibly tweakable.
I hope this helps!
EDIT: Everything in HAML
-# app/views/errors/_error.html.haml
= content_for :message do
- if model.errors.any?
%ul
- model.errors.full_messages.each do |msg|
%li= msg
-# app/views/layouts/application.html.haml
= yield :message
= render 'errors/error', model: #some_model
-# app/views/errors/_collection.html.haml
- collection.each do |model|
= render 'errors/errors', model: #some_model
= render 'errors/_collection', collection: #some_model.some_has_many_association
I guess that the [#post, #post.comments.build] array is just passed to polymorphic_path inside form_for. This generates a sub-resource path for comments (like /posts/1/comments in this case). So it looks like your first example uses comments as sub-resources to posts, right?.
So actually the controller that will be called here is the CommentsController. The reason why Lukas' solution doesn't work for you might be that you actually don't use #post.comments.build inside the controller when creating the comment (it doesn't matter that you use it in the view when calling form_for). The CommentsController#create method should look like this (more or less):
def create
#post = Post.find(params[:post_id]
#comment = #post.comments.build(params[:comment])
if(#comment.save)
# you would probably redirect to #post
else
# you would probably render post#show or wherever you have the form
end
end
Then you can use the code generated by scaffolding, only replace #post instance variable with #comment in all the lines except form_for call.
I think it may also be a good idea to add the #comment = #post.comment.build to the controller method that displays this form and use form_for([#post, #comment], ...) to keep the form contents displayed in the form if there're errors.
If this doesn't work and you're not able to figure it out, please add your CommentsController#create method to the question.
I just looked into the docrails github issues, and they've decided to remove f.error_messages instead of explaining how to do validation for comments.
a rather simple implementation can be achieved with
class ActionView::Helpers::FormBuilder
def error_message(method)
return unless object.respond_to?(:errors) && object.errors.any?
#template.content_tag(:div, object.errors.full_messages_for(:"#{method}").first, class: 'error')
end
end
which allows one to use
<%= form.label :first_name %>
<%= form.text_field :first_name %>
<%= form.error_message :first_name %>
and with the following sass
#import variables
.error
padding: $margin-s
margin-left: $size-xl
color: red
.field_with_errors
input
border: 1px red solid
input:focus
outline-color: red
it looks like
using simple form gives you quite similiar functionality with more advanced functionality.
For example check out their examples with bootstrap