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 :)
Related
I have successfully used Jquery Autocomplete for other forms on my website but this one is giving me trouble.
// Controller
class UsersController < ApplicationController
autocomplete :user, :name,
...
end
// Routes
resources :users do
get :autocomplete_name, :on => :collection
end
//View
<% form_tag users_path, method: :get do %>
<%= autocomplete_field_tag :name, params[:name], autocomplete_name_users_path, :placeholder => "Search by name" %>
<%= submit_tag "Search", :id => "submit" %>
<% end %>
The search form works but the auto complete is not showing.
Please replace with following in routes.rb file,
resources :users do
get :autocomplete_user_name, :on => :collection
end
Please refer Rails 4 autocomplete for more documentation.
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.
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).
I've got a page which loads at home.html.erb and is controlled by the pages controller.
In the page, I have a form which is a single field that will be used to take email addresses.
The error I'm getting is:
undefined method `signups_path'
Here's my code for your reference, I'm not sure how exactly to define where the route is that it goes.
Home.html.erb contains this form:
<%= form_for(#signup) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Enter" %>
</div>
<% end %>
The Pages controller contains:
class PagesController < ApplicationController
def home
#title = "Open Domain - Liberate your domains from obscurity"
#signup = Signup.new
end
end
The Signup controller contains:
class SignupController < ApplicationController
def show
#signup = Signup.new
end
def new
end
def create
#signup = Signup.new(params[:signup])
if #signup.save
else
render 'new'
end
end
end
And the signup model contains:
class Signup < ActiveRecord::Base
attr_accessible :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates(:email, :presence => true,
:length => {:maximum => 40},
:format => {:with => email_regex})
end
Any help would be hugely appreciated it. I have a feeling this is a tiny problem and I'm a beginning dev. Thanks!
The form_for(#signup) is trying to build a route to POST to. If you don't have a named route in your routes.rb, you'll get this error. Try:
routes.rb
post '/signup', :to=>"signup#create", :as=>"signups"
this basically says: When a POST to the '/signup' path is requested, route it to the create action in the signup controller. Also, make a helper to this path accessible with the name: "signups_path"
You can replace your form_for tag with this:
<%= form_for #signup, :url => { :action => "create" } do |f| %>
This will post it to "signup/create".
I'm super new to Ruby on Rails. I'm trying to make an authentication system using Authlogic (following this tutorial). The error that I'm getting is right after I submit the login form:
No route matches "/user_sessions/%23%3CUserSession:0x103486aa8%3E"
Surprisingly the URL of the page right after the form is submitted which also brings up the error is:
http://localhost:3000/user_sessions/%23%3CUserSession:0x103486aa8%3E
I have no idea what I have done wrong and where that weird UserSession code thing is coming from!!!
This is how my login form looks like:
<% form_for #user_session do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :username %><br />
<%= f.text_field :username%>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
Here is my UserSession class:
class UserSession < Authlogic::Session::Base
def to_key
new_record? ? nil : [ self.send(self.class.primary_key) ]
end
end
and the create action of my UserSessionController:
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default root_path
else
render :action => :new
end
end
"redirect_back_or_default" method in ApplicationController:
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
And lastly everything related to user_sessions in routes.rb:
resources :user_sessions
match 'login' => "user_sessions#destroy", :as => :login
match 'logout' => "user_sessions#destroy", :as => :logout
These are the codes that I thought could be involved in getting that error. If I should add some more code to make it more clear please let me know.
Ok, first, you have a bad route:
match '/login', :to => 'user_sessions#new', :as => 'login'
note the new instead of destroy
also, the to_key is not needed in later versions - I'm using rails 3 and don't have it in my UserSession Model.
Definitely need to change your route to not match login to destroy.
Here's the route setting I have... (from "Agile Web Development with Rails" example).
controller :user_sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end