I'm using Rails 3.2 and Ruby 4. When I browse to http://localhost:3000/account/new I get an error:
NoMethodError in Accounts#new
Showing D:/row/dev/basic/app/views/accounts/_form_account.html.erb where line #1 raised:
undefined method `accounts_path' for #<#<Class:0x42c8040>:0x6daa960>
Extracted source (around line #1):
1: <%= form_for(#account) do |f| %>
2:
3: <div>
4: <%= f.label :username %><br>
I created Account views using rails generate controller Controllernames index show new edit delete. I also ran rails generate model account.
According to the online Rails course I'm following this should create in routes.rb:
Edit: I used rails generate model accounts, so with the s at the end.
resources :accounts
get 'accounts/:id/delete' => 'accounts#delete', :as => :accounts_delete
However, this was not created in routes.rb. My routes.rb after some editing is:
Basismysql::Application.routes.draw do
# Public pages
get '/page1' => 'pages#page1'
get '/page2' => 'pages#page2'
get '/page3' => 'pages#page3'
get "/account/index" => 'accounts#index'
get "/account/show" => 'accounts#show'
get "/account/new" => 'accounts#new'
get "/account/edit" => 'accounts#edit'
get "/account/delete" => 'accounts#delete'
get 'account/:id/delete' => 'accounts#delete', :as => :accounts_delete
devise_for :users
root :to => 'pages#index'
end
New.html.erb is:
<div class="container">
<h1>Accounts#new</h1>
<p>Find me in app/views/accounts/new.html.erb</p>
</div>
<div class="container">
<%= render "form_account" %>
</div>
And _form_account.html.erb is:
<%= form_for(#account) do |f| %>
<div>
<%= f.label :username %><br>
<%= f.text_field :username %>
</div>
<div>
<%= f.label :firstname %><br>
<%= f.text_field :firstname %>
</div>
<div>
<%= f.label :lastname %><br>
<%= f.text_field :lastname %>
</div>
<div>
<%= f.label :organisation %>
<%= f.text_field :organisation %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Part of the account controller is:
def new
#account = Account.new
end
def create
#account = Account.new(account_params)
if #account.save
redirect_to(:action => 'index')
else
render('new')
end
end
private
def account_params
params.require(:account).permit(:username, :firstname, :lastname, :organisation)
end
get "/account/index" => 'accounts#index'
get "/account/show" => 'accounts#show'
get "/account/new" => 'accounts#new'
get "/account/edit" => 'accounts#edit'
get "/account/delete" => 'accounts#delete'
get 'account/:id/delete' => 'accounts#delete', :as => :accounts_delete
This isn't the way you should create routes, they are all unnamed(besides the last one), non-restful and all are get, replace this with
resources :accounts
And your error will gone
This works
rails generate controller accounts index show new edit destroy
Note: you must use accounts and not account while generating the controller
rails generate model account
Note: you must have account as singular
in routes.rb
map.resources :accounts /or
resources :accounts
depending upon the version of rails
In addition to:
resources :accounts
you probably need:
resource :account
You've started it by adding the routes piece-meal to the routes file, but some of those need to be PUTs or POSTs or DELETEs. resource :account is a simpler shortcut to do it (correctly).
Related
i'm new in rails so i tried to do this to add a role, making a form to update and if the user update succsessfully add the role.
note: i'm using devise and rolify with cancancan
routes
get 'users/becomepartner' => 'users#becomepartner' do
collection do
patch 'update_partner'
end
end
and this is my users controller
def becomepartner
#user = current_user
end
def update_partner
#user = User.find(current_user.id)
if #user.update_with_password(partner_params)
self.add_role(:partner)
# Sign in the user by passing validation in case their password changed
bypass_sign_in(#user)
redirect_to root_path, notice: 'now you can create'
else
render :becomepartner
end
end
private
def partner_params
# NOTE: Using `strong_parameters` gem
params.require(:user).permit(:name, :style, :current_password, :email)
end
and this is my view becomepartner.html
<div>
<%= form_for(#user, :url => { :action => "update_partner" } ) do |f| %>
<div class="field">
<%= f.label :style %>
<%= f.text_field :style %>
</div>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i>
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<% end %>
</div>
In form action you have mentioned action as partner_update but you don't have that action. Change it to update_partner.
You are using the collection route for another individual route, that is get 'users/becomepartner'. So this will generate the collection route with url like:
users/becomepartner/update_partner
You can confirm this by running rake routes.
But your forms action url will be different.
What you can do is create this collection route inside users resource route like:
resources :users do
collection do
patch 'update_partner'
end
end
Then in form_for url option, use update_partner_users_path
If you don't want the users resources routes, then just define a single route like:
get 'users/becomepartner' => 'users#becomepartner'
patch 'user/update_partner' => 'users#update_partner'
I have not ran any of this code, so if there is any syntax error then post it in comment.
In routes.rb,change
patch 'update_partner' to update 'update_partner' and remove collection as you are not operating on a collection.you have added it in a do block,instead add a one liner route path.
in the form,url must be update_partner and NOT partner_update .
I'm new to ROR. I'm trying to create a page for parking permit application. I encountered this problem
I couldn't find the problem. Or maybe i missed something. Any help is appreciated.
This is my permit_controller.rb
class PermitController < ApplicationController
before_action :set_permit, only: [:show, :destroy]
def index
#permit = Permit.all
end
def new
#permit = Permit.new
end
def create
#permit = Permit.new(user_params)
if #permit.save
redirect_to root_path
else
flash[:success] = "Welcome to your profile!"
end
end
def destroy
end
def show
#permit = Permit.find(params[:id])
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
#permit = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration,:permitstart,:permitend)
end
end
This is my permit/new.html.erb
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#permit) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :"Vehicle Type" %>
<%= f.text_field :vehicle_type, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
<%= f.label :department %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :"Car Plate" %>
<%= f.text_field :carplate, class: 'form-control' %>
<%= f.submit "Confirm", class: "btn btn-primary" %>
<% end %>
</div>
</div>
This is my route.rb
Rails.application.routes.draw do
resources :users
resources :permit
get 'permit/destroy'
get 'permit/show'
root 'static_pages#home'
get 'homepage/index'
post 'permit' => 'permit#create'
get 'permitapplication' => 'permit#new'
get 'adminlogin' => 'admin_controller#index'
get 'contact'=> 'static_pages#contact'
get 'about' => 'static_pages#about'
get 'signup' => 'users#new'
get 'help' => 'static_pages#help'
post 'users' => 'users#create'
get 'login' => 'sessions#new' #Page for a new session
post 'login' => 'sessions#create' #Create a new session
delete 'logout'=>'sessions#destroy' #Delete a session
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Instead resources :permit use resources :permits.
The biggest issue here is you don't have permit/new in your routes.rb file.
As has already been suggested, it might be better for you to leverage rails
with a resources call
in routes.rb
resources :permits
and remove lines
get 'permit/destroy'
get 'permit/show'
etc.
I'll attempt to consolidate our various answers and comments.
To solve your current problem, in config/routes.rb, change resources :permit to resources :permits. This exposes all seven RESTful routes for use in your application. (This also makes obsolete the custom permit routes, unless you're explicitly calling them from within their respective forms.) Information about RESTful routes/resources here: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
Why is this valuable?
It's how your application knows to use controller actions in combination with views (and therefore forms). Say you have an edit action in your permits controller and app/views/permits/edit.html.erb has a form. Within this page's edit form, you need only have form_for #permit and Rails does all the rest. It knows you're using this particular route. I recommend you read about routing within Rails.
Please keep in mind Ruby on Rails has been carefully crafted to make things easy for you, the developer.
Ruby 2.2.4
Rails 4.2.6
PostgreSQL 9.5
I am trying to save a simple model, but when I submit the form, my browser url shows this "http://localhost:8080/notes/new?utf8=%E2%9C%93&authenticity_token=z0cyVNfUKYWDSDASDWFFZ96zj29UTtDYe8dLlKrI6Mbznb2SrTWNm%2BQ91D2s2AASD2345Fl3fTOneCC2dNg%3D%3D¬e%5Btitulo%5D=ddddddd¬e%5Bconteudo%5D=dddddddddddddddddd&commit=Create"
I am curious about this because other project, it has the same methods, same routes, the only difference is the model that only have one column, but it works fine.
def change
create_table :notes do |t|
t.text :titulo
t.text :conteudo
t.timestamps null: false
end
My controller: notes_controller.rb
def new
#note = Note.new
end
def create
#note = Note.new(note_params)
if #note.save
redirect_to '/'
else
render 'new'
end
end
private
def note_params
params.require(:note).permit(:titulo,:conteudo)
end
my form
<%= form_for(#note) do |f| %>
<div class="field">
<%= f.label :titulo %><br>
<%= f.text_area :titulo %>
<%= f.label :conteudo %><br>
<%= f.text_area :conteudo %>
</div>
<div class="actions">
<%= f.submit "Create" %>
</div>
<% end %>
my routes
Rails.application.routes.draw do
root 'notes#index'
get 'notes/new' => 'notes#new'
post 'notes' => 'notes#create'
I saw this post Rails form issuing GET request instead of POST request
but does not work for me.
Edit:
I fix it thanks to Anthony E, his answer made me look back to code and realize that I have a form inside a form. The outer form was in application.html.erb.
Thanks to all.
Rails can't infer the appropriate form route from your model. Try explicitly setting the form URL and submit method in your form_for:
form_for #note, url: "/notes", as: :note, html: { method: :post } do |f|
end
Alternatively, it may be simpler to use resourceful routing:
In routes.rb:
resources :notes, only: [:new, :create, :index]
This will create the following routes:
GET /notes/new # Maps to NotesController#new
POST /notes # Maps to NotesController#create
GET /notes # Maps to NotesController#index
I'm trying to add edit functionality to my web app, and am having some trouble. The error page I get back when I try to complete an edit of my Request object indicates that it couldn't find the right route, but the same error page contains a list of routes which includes the route it's looking for. So I'm a bit flummoxed.
The "new" method is almost identical to this edit method and the pages are almost identical as well.
The error page begins No route matches [POST] "/requests/19/edit" and then, partway down the route listing, I see this:
requests_path GET /requests(.:format) requests#index
POST /requests(.:format) requests#create
new_request_path GET /requests/new(.:format) requests#new
edit_request_path GET /requests/:id/edit(.:format) requests#edit
request_path GET /requests/:id(.:format) requests#show
PATCH /requests/:id(.:format) requests#update
PUT /requests/:id(.:format) requests#update
DELETE /requests/:id(.:format) requests#destroy
So Rails seems to be generating a request_path which expects a PATCH, not a POST, right?
routes.rb
Rails.application.routes.draw do
root "pages#index"
resources :destinations
resources :users
resources :manifests
resources :requests
:
request.rb
class Request < ActiveRecord::Base
validates_presence_of :justification
validates_presence_of :required_by
belongs_to :user
belongs_to :manifest
belongs_to :network
has_many :uploaded_files
scope :sorted, lambda{ order("required_by") }
end
edit.html.rb
<% #page_title = "Update Request" %>
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="requests edit">
<h2>Update Request</h2>
<%= form_for :request, url: request_path(#request) do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<div class="form-buttons">
<%= submit_tag("Update Request") %>
</div>
<% end %>
</div>
requests_controller.rb
def update
#request = Request.find(params[:id])
p = {'file' => params[:request][:uploaded_file], 'request_id' => #request.id}
uf = UploadedFile.create(p)
if #request.update_attributes(request_params)
flash[:notice] = "Request updatred succesfully"
redirect_to :action => 'show', :id => #request.id
else
render 'edit'
end
end
What have I missed?
Change
<%= form_for :request, url: request_path(#request) do |f| %>
to
<%= form_for :request, url: request_path(#request), method: :patch do |f| %>
in your edit.html.erb
form_for(as you are using it) sets POST as default HTTP verb. You need to alter it by setting method :patch which responds to the update action.
You can simplify it to just
<%= form_for #request do |f| %>
Check the APIdoc for more Info.
Rails 3.2
I use the Mail_form gem (from plataformatec) to create a simple 'contact us' form for my website. When click on 'send' I get a routing error that says:
Routing Error
No route matches [POST] "/contactus"
Try running rake routes for more information on available routes.
I have a very simple setup, but I am new to Rails and am still getting the hang of it. I only want the form to send an email to a certain email address... nothing else. I understand the problem is in routes.rb but I have been fiddling with this for so long I just can't figure out what is wrong. I have never struggled with a Rails error so much. PLEASE HELP!
'Pages' Model: app/models/pages.rb
class Page < MailForm::Base
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i
attribute :page_title, :validate => true
attribute :page_body, :validate => true
def headers
:subject => "#{page_title}",
:to => "careers#example.com",
:from => %("#{name}" <#{email}>)
end
end
'Pages' Controller: app/controllers/pages_controller.rb
class PagesController < ApplicationController
respond_to :html
def index
end
def create
page = Page.new(params[:contact_form])
if page.deliver
redirect_to contactus_path, :notice => 'Email has been sent.'
else
redirect_to contactus_path, :notice => 'Email could not be sent.'
end
end
end
Form Partial: app/views/pages/_form.html.erb
<%= simple_form_for :contact_form, url: contactus_path, method: :post do |f| %>
<div>
<%= f.input :name %>
<%= f.input :email, label: 'Email address' %>
<%= f.input :page_title, label: 'Title' %>
<%= f.input :page_body, label: 'Your message', as: :text %>
</div>
<div class="form-actions">
<%= f.button :submit, label: 'Send', as: :text %>
</div>
View (called contactus): app/views/pages/contactus.html.erb
<body>
<div>
<h2 class="centeralign text-info">Contact Us</h2>
</div>
<div class="container centeralign">
<%= render 'form' %>
</div>
<h2>We'd love to hear from you! </h2><br /><h4 class="muted">Send us a message and we'll get back to you as soon as possible</h4>
</div>
</div>
</body>
Routes.rb
Example::Application.routes.draw do
resources :pages
root to: 'pages#index', as: :home
get 'contactus', to: 'pages#contactus', as: :contactus
get 'services', to: 'pages#services', as: :services
Your routes.rb file doesn't have a route for POST /contactus
You've got a route for GET /contactus but no POST, so what rails is saying is correct.
Just add something like
post 'contactus', to: 'controller#action'
With whatever controller and action you need to call. Alternatively, if you're trying to call the create action in the pages controller, then your problem is that where you've added resources :pages to routes, you've actually create the route
post 'pages'
So in that case, I'd change your simple_form_for url to post to there instead. Try using
simple_form_for :contact_form, url: pages_path, method: :post do
instead. If pages_path doesn't work, then just run rake routes in a console and you'll see a list of all of the routes you have including their names. Then just pick the one you need for this :)