is there a way to execute code and then redirect inside the routes-file like this:
get 'cache/clear' => Proc.new { Rails.cache.clear && redirect('/') }
I just really don't want to create a controller for this particular action.
Yup. See here: http://www.railsdispatch.com/posts/rails-routing
match "/foo", :to => proc {|env| [200, {}, ["Hello world"]] }
or, more specifically for your case
match "cache/clear", :to => redirect {Rails.cache.clear && '/'}
Related
I have a Rails Application in which I have used force_ssl method as
def force_ssl # to use https for payment page
if !Rails.env.development? && !request.ssl?
redirect_to :protocol => 'https'
end
end
for a Particular action name 'abc' with named route
match '/find-a-abc' => "home#abc"
when I go to URL
http://local.demo.com/find-a-abc
it will redirect_to https://local.demo.com/abc
Any Solution? so it will redirect_to Particular route, rather than redirecting to an Action when using a https Protocol.
It doesn't look like you've provided a named route here (i.e. match '/find-a-abc' => "home#abc", :as => :named_route). You will need to do this and call named_route_url rather than just the controller and action to get the right URL.
If you want a specific route to always be handled with SSL, you could define the route like so:
scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
match '/find-a-abc' => "home#abc", :as => :abc
end
Then abc_url should always be "https://local.demo.com/find-a-abc"
Is it possible to route a request depending on a session value?
I would like to route /test to test#withoutsession or /test to test#withsession depending on a session value.
Your best bet is probably applying dynamic constraints to your routes, like this:
get '/test', :to => 'test#withoutsession', :constraints => lambda{ |req| req.session[:user_id].blank? }
get '/test', :to => 'test#withsession', :constraints => lambda{ |req| req.session[:user_id].present? }
Reference: http://edgeguides.rubyonrails.org/routing.html#advanced-constraints
On a rails 3 app, I've got these routes defined:
devise_for :users, :controllers => {:omniauth_callbacks => "users/omniauth_callbacks", :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :sign_out => 'logout' } do
get 'login' =>'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
get 'signup' => 'registrations#new', :as => :new_user_registration
get 'signout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
# catchall route to deal with routing errors
match "*path" => "error#index"
However, now when I go to log /user/auth/facebook, it routes me to the errors page...
My solution to this was to add constraints to the final match:
match "*path" => "error#index", :constraints => lambda {|req| !req.path.starts_with?("/users/auth/") }
This works, but I am wondering if there is a better way... ?
I think you are better off letting a 404 page handle routing errors. You only get a 500 error in development. It's a 404 in production. For example on my site: http://agmprojects.com/test. So i suggest using the 404.html in the public folder instead, rather than loading that controller. Out of curiosity, are you responding with a 404 http status code?
I have a custom redirection in my routes.rb which works fine at the ui:
match ':hash' => redirect { |params| begin url = Sharing.find_by_short_url(params[:hash]); "/#{url.shareable_type}/#{url.shareable_id}/" rescue '/' end }, :constraints => { :hash => /[a-zA-Z0-9]{7}/ }
What is does is takes a shortened url and looks up the actual url path.
However my test is failing:
it "routes GET 'STU1VWX' to stations/1" do
{ :get => "STU1VWX" }.should redirect_to(
:controller => "stations",
:action => "show",
:params => {:id => 1}
)
end
With:
1) Shorter URL redirect routes GET 'STU1VWX' to stations/1
Failure/Error: { :get => "STU1VWX" }.should route_to(
ActionController::RoutingError:
No route matches "/STU1VWX"
# ./spec/routing_spec.rb:12:in `block (2 levels) in <top (required)>'
So the problem is isolated at the test level. I know I could test this in a controller test but given that the code is in routes.rb I should not have to. Is there inherently a reason that using should route_to not to work in the case of redirection?
Looks like you're saying here that if you can't find the page belonging to the hash, then redirect to "/"
There's something really stinky about performing an ActiveRecord find in your routes.
If you have to redirect to a specific controller depending on the sharable type, then I'd put this as a separate controller with a redirect:
match "/:hash" => 'SharableController#redirect':constraints => { :hash => /[a-zA-Z0-9]{7}/ }
and then deal with finding the record and redirecting to the correct controller action from there:
class SharableController < ApplicationController
def redirect
#sharable = Sharable.find_by_sharable_type(params[:hash])
redirect_to controller: #sharable.sharable_type, action: 'show', id: #sharable.id
end
end
OR... depending on how similar the show actions are:
class SharableController < ApplicationController
def redirect
#sharable = Sharable.find_by_sharable_type(params[:hash])
render template: "#{#sharable.sharable_type.pluralize}/show"
end
end
If you're only dealing with GET requests, better to swap out match for get by the way:
get "/:hash" => 'SharableController#redirect', :constraints => { :hash => /[a-zA-Z0-9]{7}/ }
I want to route requests something like this: reports/bloodtypes is routed to controller reports, action bloodtypes, with format = pdf, and the route named as bloodtype_report. The Guides gives an example
match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
When I do this:
match 'reports/bloodtypes' => 'reports#bloodtypes', :defaults => {:format => 'pdf'}, :as => 'bloodtype_report'
or this
match 'reports/bloodtypes' => 'reports#bloodtypes', :format => 'pdf', :as => 'bloodtype_report'
the controller still does not receive the :format => 'pdf' in params, and tries to render the report as HTML. The funny thing is that the route is shown by Rake as
bloodtype_report : /reports/bloodtypes(.:format) : {:format=>"pdf", :controller=>"reports", :action=>"bloodtypes"}
whether I use the first form (with :default) or second (just setting the format to pdf). It seems the route is correct, so why is the format parameter not being passed to the controller?
have you tried adding this to your controller:
respond_to do |format|
format.html
format.pdf { render :pdf => "show" }
end