:via => [:options] in ruby on rails routes - ruby-on-rails-3

In some Rails app, I saw this in the routes.rb
root :to => "home#index", :via => [:get]
root :to => "accounts#manage", :via => [:options]
I could not understand how these two root URLs can exist. Googling didn't help clear the :options argument either. Can anyone help?
Thanks

As per the HTTP spec (and explained a bit more here), there is an OPTIONS verb - which routes can support.
The impetus for using OPTIONS is to request documentation for a web service API; results are meant to provide information regarding how the API may be used.
ActionDispatch::Routing::HTTP_METHODS
=> [:get, :head, :post, :put, :delete, :options]
To get back to your question, in a typical browser GET request, the first route will be used. When an OPTIONS request is made, the second route will be used.

You can use the :via option to constrain the request to one or more HTTP methods
See the rails guide on routing
:post, :get, :put, :delete, :options, :head, and :any are allowed as a value to this option.
As explained in a blog post, OPTIONS is just another HTTP verb to support CORS requests (a way to make cross domain AJAX requests).
Update found a blog post explaining :options

For Rails 5 and above:
in routes.rb
match "/404", :to => "errors#not_found", via: :all
match "/500", :to => "errors#internal_server_error", via: :all
For controller:
class ErrorsController < ApplicationController
layout 'xyz'
def not_found
end
def internal_server_error
end
end
This will work in production, if you want the same for the development also, then in development.rb
change:
config.consider_all_requests_local = false

Related

Select SSL Routes serving up rails 4 static pages via highvoltage gem

I have several static erb pages being served up in a ruby rails 4 site via the high voltage gem:
get '/about' => 'high_voltage/pages#show', id: 'about'
get '/contact' => 'high_voltage/pages#show', id: 'contact', :protocol => "https"
get '/privacy' => 'high_voltage/pages#show', id: 'privacy'
This all works well and good, except that the /contact route doesn't redirect or force SSL on, it is happy with whatever protocol is used.
I host the site on engine yard, attempting to put :force_ssl only or variants in the route line resulted in failed deployments - high voltage uses a slightly different set of arguments than normal routes so I suspect there is a conflict somewhere.
Anyone use highvoltage and SSL with rails 4 for select static pages (not the whole site)? Example routes line please.
You can achieve this by overriding the HighVoltage#PagesController see the override section of the documentation.
It might look something like this:
class PagesController < ApplicationController
include HighVoltage::StaticPage
before_filter :ensure_secure_page
private
def ensure_secure_page
if params[:id] == 'contact'
# check to make sure SSL is being use. Redirect to secure page if not.
end
end
end
Next disable the routes that HighVoltage provides:
# config/initializers/high_voltage.rb
HighVoltage.routes = false
Then in your application's routes file you'll need to set up a new route:
# config/routes.rb
get "/pages/*id" => 'pages#show', as: :page, format: false

How to override devise invitable actions

I am using devise-invitable gem in my application. If the user exists in the application and he clicks accept invitation link he should be redirected to sign in page other if new user clicks the link he should be redirected to sign up page. I am not getting how I can override the after_accept_path_for method for that...Where and how can I override this method, can some one please help me in this?
Following https://github.com/scambra/devise_invitable/ link
I think you might want to re-read the documentation, your question is answered in the docs, just not all in one place.
Here are the two sections that concern your question:
https://github.com/scambra/devise_invitable#configuring-controllers
https://github.com/scambra/devise_invitable#integration-in-a-rails-application
Basically you're going to add a controller for invitations and add routing information for that controller (app/controllers/users/invitations_controller.rb) like this:
class Users::InvitationsController < Devise::InvitationsController
def after_accept_path_for
"some path you define"
end
end
Then you'll change your routes.rb to tell devise to use your invitations controller like:
devise_for :users, :controllers => { :invitations => 'users/invitations' }
With devise 2.1.2 and devise_invitable 1.1.8, the page you end up on after setting password from the invitation link depends on what you set the root path for your devise resource in the config/routes.rb so #trh's answer doesn't work with this version (I tried and failed). From the devise code comments:
# The default url to be used after signing in. This is used by all Devise
# controllers and you can overwrite it in your ApplicationController to
# provide a custom hook for a custom resource.
#
# By default, it first tries to find a valid resource_return_to key in the
# session, then it fallbacks to resource_root_path, otherwise it uses the
# root path. For a user scope, you can define the default url in
# the following way:
#
# map.user_root '/users', :controller => 'users' # creates user_root_path
#
# map.namespace :user do |user|
# user.root :controller => 'users' # creates user_root_path
# end
#
# If the resource root path is not defined, root_path is used. However,
# if this default is not enough, you can customize it, for example:
#
# def after_sign_in_path_for(resource)
# stored_location_for(resource) ||
# if resource.is_a?(User) && resource.can_publish?
# publisher_url
# else
# super
# end
# end
In my case, I had two different namespaces with one namespace called "portal" which I was using a "PortalUser" class for the user. For Rails 3.2, I simply declared this line in my routes.rb:
get "portal" => 'portal/dashboard#index', as: :portal_user_root
The important note is the naming, "portal_user_root" which is the underscored name of PortalUser class name. Simply setting this named route is all that's needed for your devise_invitable to redirect as desired.

RoutingError resulting from 'redirect_to root_url' not passing action

With a standard install of Rails_Admin using Devise for authentication and CanCan for authorization, accessing http://localhost:3000/admin as a non-admin user produces the following server log:
Started GET "/admin" for 127.0.0.1 at 2011-08-09 22:46:10 -0400
Processing by RailsAdmin::MainController#index as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Completed 404 Not Found in 151ms
ActionController::RoutingError (No route matches {:controller=>"gyms"}):
app/controllers/application_controller.rb:5:in `block in <class:ApplicationController>'
Everything up until the last part seems ok. As far as I can tell, CanCan rescues the exception properly and attempts to redirect to root_url via the following code:
class ApplicationController < ActionController::Base
protect_from_forgery
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
end
TopOut::Application.routes.draw do
mount RailsAdmin::Engine => '/admin', :as => 'rails_admin'
devise_for :users
resources :gyms
root :to => "gyms#index"
end
But for some reason, in redirecting to root_url, CanCan is only attempting to hit
{:controller=>"gyms"}
rather than
{:controller=>"gyms", :action=>"index"}
Is this possibly an issue with CanCan? Or is there some particular facet of redirect_to or root_url which I missed in the docs?
Note: this is a duplicate of an issue I opened on CanCan's github page, so I'll be sure to close one if the other is solved.
Based on feedback from users at Github, it appears that routes are being name_scoped and so this is expected behavior.
Proper fix is to call root_url from main_app as follows:
rescue_from CanCan::AccessDenied do |exception|
redirect_to main_app.root_url, :alert => exception.message
end
Credit for the solution goes to bbenezech at https://github.com/sferik/rails_admin/issues/658

Default root url and display the controller action rather than "/" in rails 3

Is there a way to set the default root routes in rails to be one of my controller action and showing in the url rather than the root "/" ?
Say I have a "Computer" controller with a "index" action.
When my user login to my application, I want the url to be
http://localhost:3000/computer/index rather than http://localhost:3000/
root :to => "computers#index"
does the latter one, how can I make the default root url to be something like the prior one ?
UPDATE: a better way would be
root :to => redirect(/path)
The simplest way would be to change which URL your users get re-directed to after they successfully log in.
You could also add a forced re-direct in your controller:
# routes.rb
root :to => "computers#force_redirect"
# computers_controller.rb
def force_redirect
redirect_to '/computers/index'
end

No route matches "/admin" error

I am writing my first application in rails and here is what I did
C:\Personal\rails\demo>ruby -v
ruby 1.9.2p136 (2010-12-25) [i386-mingw32]
C:\Personal\rails\demo>rails -v
Rails 3.0.5
C:\Personal\rails\demo>rails generate model book
invoke active_record
create db/migrate/20110325190010_create_books.rb
create app/models/book.rb
invoke test_unit
create test/unit/book_test.rb
create test/fixtures/books.yml
C:\Personal\rails\demo>rake db:migrate
(in C:/Personal/rails/demo)
== CreateBooks: migrating ====================================================
-- create_table(:books)
-> 0.0000s
== CreateBooks: migrated (0.0000s) ===========================================
C:\Personal\rails\demo>rails generate controller admin
create app/controllers/admin_controller.rb
invoke erb
create app/views/admin
invoke test_unit
create test/functional/admin_controller_test.rb
invoke helper
create app/helpers/admin_helper.rb
invoke test_unit
create test/unit/helpers/admin_helper_test.rb
Then i edited the admin_controller.rb as follows:
class AdminController < ApplicationController
scaffold :book
end
Here is the routes.rb file
Demo::Application.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => "welcome#index"
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
end
However, when I go to http://localhost:3000/admin, I get a "No route matches "/admin"" error. I noticed that my routes.rb has only the commented lines. Did I do something wrong?
You have not added a route for admin, why are all your routes commented out.
if admin is a resource add this line
resources :admin
Also in your controller you will need an index method and index view file because http://localhost:3000/admin will take you there
Try removing the comment from this line:
match ':controller(/:action(/:id(.:format)))'
Note: This answer is for the case when above mentioned points are met yet you keep seeing this error. It was Rails 3.2 and Ruby 2.3.8
Problem definition:
I successfully logged in using admin creds. When page landed on /admin I saw No route matches [GET] "/admin" error page. I hit my head everywhere and used all my knowledge. Also, generated routes and grep but no admin route was published.
$ rake routes | grep admin
but only devise related admin routes were published. And then I read the warning about the routes which I noticed later, which goes like
ActiveAdmin: ActiveAdmin::DatabaseHitDuringLoad: Your file, app/admin/account_tags.rb (line 4),
caused a database error while Active Admin was loading. This is most common
when your database is missing or doesn't have the latest migrations applied.
To prevent this error, move the code to a place where it will only be run
when a page is rendered. One solution can be, to wrap the query in a Proc.
Original error message: PG::UndefinedTable: ERROR: relation "account_tags" does not exist
Solution
I ran rake db:migrate and restarted the server, the problem was gone.