Rails 4: Invalid route name, already in use (ArgumentError) - ruby-on-rails

Well the error is telling the truth, I have used the route name 'contact' twice, but one match is for a get request and the other for a post. I have been following the following tutorial for setting up Contact Form in Rails: http://matharvard.ca/posts/2011/aug/22/contact-form-in-rails-3/, and the author suggests adding the following to my routes file:
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
However that gives me the following error:
Invalid route name, already in use: 'contact' (ArgumentError)
Here is my own routes.rb file:
Fls::Application.routes.draw do
root 'welcome#index'
match 'contact' => 'contact#new', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
end

Do the following instead of above:
resource :contact, only: [:new, :create]
OR
get 'contact' => 'contact#new'
post 'contact' => 'contact#create', :as => 'contact'

Related

Why default locale does not work?

In my application controller, I am forcing locale handling as a before filter:
before_filter :set_locale
def set_locale
#I18n.default_locale is en
I18n.locale = extract_locale_from_tld || I18n.default_locale
end
def extract_locale_from_tld
parsed_locale = params[:locale] || ((lang = request.env['HTTP_ACCEPT_LANGUAGE']) && lang[/^[a-z]{2}/])
#so, english is the default language.
parsed_locale= 'en' if parsed_locale.nil?
I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
end
However, if I tried to visit http://localhost:3000/ko/lab it would result into routing error which is error 404 eventually.
Any locale out of the following locates will result into routing error:
Any advice?
EDIT
My route.er:
# -*- encoding : utf-8 -*-
MyApp::Application.routes.draw do
mount Alchemy::Engine => 'blog'
Rails.application.routes.draw do
filter :pagination, :uuid, :locale
end
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks",
:sessions => "users/sessions",
:registrations => "users/registrations"}
resources :authentications
resources :experiments
get 'experiments/:id/info_edit' => 'experiments#info_edit',:constraints => { :id => /\d+/ }
get 'sitemap.xml', :to => 'sitemap#index', :defaults => {:format => 'xml'}
match 'lang' => 'home#set_lang', :via => [:get]
#match 'free_trial' => 'home#free_trial', :via => [:get]
match 'useful_links' => 'home#useful_links', :via => [:get]
match 'home' => 'home#home', :via => [:get]
match 'contact-us' => 'contact#new', :as => 'contact_us', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
match 'dashboard' => 'experiments#index', :via => [:get]
post 'notifications' => 'subscriptions#instant_payment_notification'
match 'users_experiments' => 'experiments#users_experiments', :via => [:get]
match 'hire_us' => 'home#hire_us', :via => [:get]
get 'lab' => 'experiments#lab'
get 'experiments/:id/review-edit' => 'experiments#review', :as => :review
get 'experiments/:id/cancel-edit' => 'experiments#cancel_edit', :as => :cancel_edit
get 'experiments/:id/approve-edit' => 'experiments#approve', :as => :approve
get 'experiments/:id/reject-edit' => 'experiments#reject', :as => :reject
get 'experiments/:id/profile' => 'experiments#profile', :as => :profile
match 'amazon' => 'experiments#amazon', :via => [:get]
match 'trial_account' => 'home#trial_account', :via => [:get]
match 'student_account' => 'home#student_account', :via => [:get]
match 'school_account' => 'home#school_account', :via => [:get]
match 'create_account' => 'home#registration_redirect', :via => [:get]
match 'users/create_account' => 'home#registration_entrance', :via => [:get]
match 'registration_redirect' => 'home#registration_redirect', :via=>[:post]
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => 'home#home'
get "/auth/oauth2/callback" => "auth0#callback"
get "/auth/verification_complete" => "auth0#verification_complete"
get "/auth/failure" => "auth0#failure"
end
My server log:
Started GET "/ko/lab" for 127.0.0.1 at 2017-09-12 08:58:56 +0300
Processing by ApplicationController#routing_error as HTML
Parameters: {"path"=>"ko/lab"} User Load (202.1ms) SELECT
"users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id"
ASC LIMIT 1 [["id", 12899]] Completed 404 Not Found in 205ms ko/lab
excluded from capture: DSN not set
ActionController::RoutingError (ko/lab):
app/controllers/application_controller.rb:35:in routing_error'
lib/rack/seoredirect.rb:20:incall'
Default local does work but you don't have a route that matches /:locale/lab. Its that simple.
You can create localized routes by using scope - Rails does not do this for you.
scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
get '/' => 'home#home' # this will map /en to home#home
get 'lab' => 'experiments#lab'
# ...
end
This is probably a good time to refactor a really messy routes file by using the resources helper to its full extent:
resources :experiments do
member do
get :info_edit
# ...
end
end
See http://guides.rubyonrails.org/routing.html#adding-more-restful-actions

Rails constraint on route that contains dynamic segment

I have the following two routes in my Rails app:
match '/users/:username' => 'users#show', :via => :get, :as => :user
match '/users(/:filter)' => 'users#index', :via => :get, :as => :users
This is so that I can have routes like:
/users/cameron
/users/popular
Where the first is a user, and the second is a filter.
However the routing in Rails will always hit the first route, because it doesn't know the difference between :username and :filter.
For posts I avoid this problem by doing:
match '/posts/:id' => 'posts#show', :via => :get, :as => :post, :id => /[0-9]/
But this only works because posts are always integers. For example: /posts/21
How can I apply a constraint to my user routes so that they don't trip over each other and without having to add a prefix to either of them.
I've tried this approach (based on the link provided by #Mario
match '/users/:username' => 'users#show', :via => :get, :as => :user, :constraints => lambda { |request| User.usernames.include?(request.params[:username]) }
and in my User model:
def self.usernames
User.pluck(:username)
end

Devise redirecting after errors

On the sign up and forgot password views in Devise, if you get an error, it redirects you to the parent page.
So on the sign up page (/users/sign_up), if you get an error, it redirects you to /users and shows the error.
On the forgot password page (/users/password/new), if you get an error, it redirects you to /users/password and shows the error.
How can I change it so it does the same thing as the sign in page, if there's an error, it stays on the same page and shows the error.
I've looked through Devise and can't find where the redirect is.
Here's my routes for Devise:
devise_for :users, :skip => [:sessions]
as :user do
get 'signin' => 'devise/sessions#new', :as => :new_user_session
post 'signin' => 'devise/sessions#create', :as => :user_session
get 'signup' => 'devise/registrations#new', :as => :new_user
post 'signup' => 'devise/registrations#create', :as => :create_user_session
delete 'signout' => 'devise/sessions#destroy', :as => :destroy_user_session
get "/account" => "devise/registrations#edit"
end
I think the problem is that you have the post 'signup' named incorrectly. What path does your user signup form POST to?
post 'signup' => 'devise/registrations#create', :as => :create_user_session
Should be:
post 'signup' => 'devise/registrations#create', :as => :user_registration
Here's a look at my routes.rb which solved this issue:
as :user do
get "/signin" => "devise/sessions#new", :as => :new_user_session
post "/signin" => "devise/sessions#create", :as => :user_session
delete "/signout" => "devise/sessions#destroy", :as => :destroy_user_session
get "/signup" => "devise/registrations#new", :as => :new_user_registration
post '/signup' => 'devise/registrations#create', :as => :user_registration
end
It doesn't redirect you anywhere, those are the URLs that Devise posts to.
If you want to edit these URLs, see the wiki for a good starting point:
https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes

Devise custom routes slippery slope

I started using custom routes w/Devise so that I could have my 'Sign In' and 'Sign Up' routes go to the same page. However, as soon as I followed the instruction from Devise about custom routes, it seems that every route now has to be explicitly specified. This has now broken my reset password links since that portion is handled by Devise.
What am I doing wrong here? You can see below that I've had to spell out everything for my User and UserSessions model. Shouldn't I only have to specify the ones I want to change?
devise_for :users, :controllers => { :sessions => "user_sessions" ,:registrations=>"users"},:skip => [:sessions] do
get 'users/sign_in' => 'user_sessions#new', :as => :new_user_session
get 'users/sign_up' => 'user_sessions#new', :as => :new_user_session
post 'users/sign_in' => 'user_sessions#create', :as => :user_session
post 'user_sessions' => 'user_sessions#create', :as => :app_sign_in
delete 'users/sign_out' => 'user_sessions#destroy', :as => :destroy_user_session
get 'users/sign_out' => 'user_sessions#destroy', :as => :destroy_user_session
post 'users/:id' => 'users#update', :as =>:update_user
get 'users' => 'users#index'
get 'users/:id/edit' => 'users#edit', :as => :edit_user
get 'users/:id' => 'users#show', :as => :show_user
delete 'users/:id' => 'users#destroy', :as => :destroy_user
end
Can you just use, not sure if this will work for you
devise_for :users
devise_for :users do
get '/users/sign_out' => 'devise/sessions#destroy'
end

Issue with routes

I have an issue with routing. I have a link to "new_company_path", but on the website it links to "site/dashboard". When I do a "rake routes" it gives the correct route for the link:
new_company GET /companies/new(.:format) {:action=>"new", :controller=>"companies"}
This is my "routes.rb":
match "/companies/:id/users" => "site#company_users", :as => :company_users
match "/company/:id/companies_user/new" => "companies_users#new"
resources :companies
get "site/index"
get "site/features"
get "site/dashboard", :as => "dashboard"
get "users_dashboard/show", :as => "users_dashboard"
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
Any reason why the link is not correct?

Resources