3. Basic routes summary part I
# Empty route
root :to => 'welcome#show'
# Regular routes
match 'products/:id', :to => 'catalog#view'
match 'products/:id' => 'catalog#view'
# Named routes
match 'logout', :to => 'sessions#destroy', :as => 'logout'
match 'logout' => 'sessions#destroy', :as => 'logout'
# Verb routes
match 'account/overview', :to => 'account#overview', :via => 'get'
get 'account/overview'
@silviorelli
mercoledì 23 maggio 12
4. Basic routes summary part II
# Resourceful routes
resources :products do
collection do
get :sold
post :export
end
member do
post :publish
end
put :toggle, :on => :member
end
# Nested resourceful routes
resources :projects do
resources :tasks, :people
end
@silviorelli
mercoledì 23 maggio 12
5. Basic routes summary part III
# Nested resourceful routes
resources :projects do
resources :tasks, :people
end
# Restricted restful routes
resources :posts, :except => [:edit]
resources :posts, :only => [:new, :create]
# REST override
resource :session do
get :create # BAD!!
end
# Altering action name
resources :projects, :path_names => { :edit => 'modify' }
@silviorelli
mercoledì 23 maggio 12
6. Routes globbing
# This route would match photos/12 or /photos/long/path/to/12,
# setting params[:other] to "12" or "long/path/to/12"
match 'photos/*other' => 'photos#unknown'
# This would match books/some/section/last-words-a-memoir with
# params[:section] equals to "some/section",
# and params[:title] equals to"last-words-a-memoir"
match 'books/*section/:title' => 'books#show'
@silviorelli
mercoledì 23 maggio 12
7. Optional segments
# Both /posts/new and /posts will be redirected to the create action in posts controller,
# but /posts/edit will not work:
match 'posts(/new)', :to => 'posts#create'
# This is an optional path scope that allows to have a prepended path before a resource:
scope '(:locale)', :locale => /en|it/ do
resources :descriptions
end
# Default generic Rails 3 route
match '/:controller(/:action(/:id))'
@silviorelli
mercoledì 23 maggio 12
9. Redirects and Constraints
# This code will redirect /foo/2 to /bar/2s:
match '/foo/:id', :to => redirect("/bar/%{id}s")
# This code will redirect /account/proc/john to /johns.
match 'account/proc/:name', :to => redirect {|params| "/#{params[:name].pluralize}" }
# Constraint on numeric id
match '/posts/show/:id', :to => 'posts#index', :constraints => {:id => /d/}
# Constraint on subdomain
match '/foo/bar', :to => 'foo#bar', :constraints => {:subdomain => 'support'}
# Constraint on ip address
match '/foo/bar', :to => 'foo#bar', :constraints => {:ip => /127.0.0.1/}
@silviorelli
mercoledì 23 maggio 12
10. More on constraints
# Arbitrary constraint
constraints(:ip => /127.0.0.1/) do
match '/questions', :to => redirect('http://www.stackoverflow.com/')
end
# Object-based constraint
class IpRestrictor
def self.matches?(request)
request.ip =~ /127.0.0.1/
end
end
constraints IpRestrictor do
match '/questions', :to => redirect('http://www.stackoverflow.com/')
end
@silviorelli
mercoledì 23 maggio 12
11. Lambdas on routes
scope :constraints => lambda{|req| req.host == $BLOG_DOMAIN } do
root :to => "posts#index"
match 'posts/archive' => 'posts#archive', :as => 'archive_post'
match 'posts/:pretty_url' => 'posts#show', :as => 'show_post'
end
scope :constraints => lambda{|req| req.host == $INTRANEWS_DOMAIN} do
root :to => "intranews#index"
resources :int, :as => :intranews, :controller => :intranews, :only => [:index, :show] do
match 'search' => 'intranews#search', :on => :collection
end
end
scope :constraints => lambda{|req| !req.session[:user_id].blank? } do
# logged users routes only
end
@silviorelli
mercoledì 23 maggio 12
12. endpoints part I
Rack provides a minimal interface between webservers supporting Ruby and Ruby frameworks.
match "/blog" => MySinatraBlogApp, :anchor => false
class MySinatraBlogApp < Sinatra::Base
get "/blog/archives" do T
mount MySinatraBlogApp, :at => "/blog" "my old posts"
# or simply end
mount MySinatraBlogApp => "/blog" end
@silviorelli
mercoledì 23 maggio 12
13. Rack endpoints part II
mount Resque::Server => '/admin/resque', :constraints LoggedInConstraint.new(true)
root :to => 'sessions#new', :constraints => LoggedInConstraint.new(false)
root :to => 'users#show', :constraints => LoggedInConstraint.new(true)
# In config/initializers/logged_in_constraint.rb
class LoggedInConstraint < Struct.new(:value)
def matches?(request)
T
request.cookies.key?("auth_token") == value
end
end
@silviorelli
mercoledì 23 maggio 12
14. Splitted routes file
# In config/application.rb
config.paths["config/routes"] << Rails.root.join('config/routes/api_routes.rb')
# In config/routes/api_routes.rb ### Coming in Rails 4 ###
Sandbox::Application.routes.draw do
# config/routes.rb T
constraints(:subdomain => 'api') do draw :admin
resources :recipes
end # config/routes/admin.rb
namespace :admin do
end resources :posts
end
@silviorelli
mercoledì 23 maggio 12
17. Routes in Models
R.I.P.
MVC
Encapsulation
@silviorelli
mercoledì 23 maggio 12
18. Routes helpers in Models part I
class Post < ActiveRecord::Base
attr_accessible :content, :name, :title
def put_routes
posts_path
end
end
1.9.3p194 :001 > Post.first.put_routes
Post Load (0.3ms) SELECT `posts`.* FROM `posts` LIMIT 1
NameError: undefined local variable or method `posts_path' for #<Post:0x007ff1a17f4e60>
@silviorelli
mercoledì 23 maggio 12
19. Routes helpers in Models part II
class Post < ActiveRecord::Base 1.9.3p194 :001 > Post.first.put_routes
attr_accessible :content, :name, :title Post Load (0.3ms) SELECT `posts`.* FROM
`posts` LIMIT 1
include ActionDispatch::Routing::UrlFor => "/posts"
include Rails.application.routes.url_helpers
default_url_options[:host] = 'example.com'
1.9.3p194 :002 > Post.first.put_instance_route
def put_routes Post Load (0.6ms) SELECT `posts`.* FROM
posts_path `posts` LIMIT 1
end => "http://example.com/posts/1"
def put_instance_route
url_for(self)
end
end
@silviorelli
mercoledì 23 maggio 12
20. Routes helpers in Models part III
class Post < ActiveRecord::Base class Post < ActiveRecord::Base
attr_accessible :content, :name, :title attr_accessible :content, :name, :title
include ActionDispatch::Routing::UrlFor include ActionDispatch::Routing::UrlFor
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
default_url_options[:host] = 'example.com' default_url_options[:host] = 'example.com'
def self.put_routes def self.put_routes
posts_path Rails.application.routes.url_helpers.posts_path
end end
end end
1.9.3p194 :001 > Post.put_routes 1.9.3p194 :001 > Post.put_routes
NameError: undefined local variable or method => "/posts"
`posts_path' for #<Class:0x007fcb9b1260d8>
@silviorelli
mercoledì 23 maggio 12
21. Routes helpers in console
1.9.3p194 :001 > posts_path
NameError: undefined local variable or method `posts_path' for main:Object
1.9.3p194 :002 > include Rails.application.routes.url_helpers
=> Object
1.9.3p194 :003 > posts_path
=> "/posts"
@silviorelli
mercoledì 23 maggio 12
22. Routes helpers in Rake Task
namespace :example do namespace :example do
desc "Example of routes helper in rake task" desc "Example of routes helper in rake task"
task :posts => :environment do task :posts => :environment do
puts "items_path = #{posts_path}" include Rails.application.routes.url_helpers
end puts "items_path = #{posts_path}"
end end
end
@Pade ➜ rake example:posts @Pade ➜ rake example:posts
rake aborted! items_path = /posts
undefined local variable or method `posts_path' for
main:Object
@silviorelli
mercoledì 23 maggio 12
24. Routes in Javascripts
js:routes # First, place the js.rake file in /lib/tasks
your_app/lib/tasks/js.rake
https://github.com/mtrpcic/js-routes # You can generate your routes file by doing the following:
rake js:routes
# The above commands will place the routes in
your_app/public/javascripts/rails_routes.js
Broken on Rails >= 3.1 # You can specify your own filename like so:
rake js:routes[custom_name.js]
$.ajax({ $.ajax({
url: "/post/" + post_id; url: post_path({id: post_id})
method: 'PUT', method: 'PUT',
data:{ data:{
x: post_x, x: post_x,
y: post_y y: post_y
} }
}); });
@silviorelli
mercoledì 23 maggio 12
25. Routes list in the browser
Visit /rails/routes in the browser
sexant gem
https://github.com/schneems/sextant
@silviorelli
mercoledì 23 maggio 12
26. i18n translable routes part I
rails-translate-routes gem
https://github.com/francesc/rails-translate-routes
# In config/locales/routes.yml
en:
# you can leave empty locales, for example the default one
es:
products: productos
contact: contacto
new: crear
products_en GET /products(.:format) {:action=>"index", :controller=>"products"}
products_es GET /es/productos(.:format) {:action=>"index", :controller=>"products"}
POST /products(.:format) {:action=>"create", :controller=>"products"}
POST /es/productos(.:format) {:action=>"create", :controller=>"products"}
@silviorelli
mercoledì 23 maggio 12
27. i18n translable routes part II
i18n_routing gem
https://github.com/kwi/i18n_routing
# In config/routes.rb :
localized do
resources :users ruby-1.8.7-p249 > I18n.locale = :en
end => :en
ruby-1.8.7-p249 > app.users_path
=> "/users"
# In config/locales/fr.yml ruby-1.8.7-p249 > I18n.locale = :fr
fr: => :fr
resources: ruby-1.8.7-p249 > app.users_path
users: 'utilisateurs' => "/utilisateurs"
@silviorelli
mercoledì 23 maggio 12
28. Less known routes
Rails Routes off the tracks
23 May 2012 by
References: Silvio Relli
http://guides.rubyonrails.org/routing.html
http://api.rubyonrails.org/classes/ActionDispatch/Routing.html silvio@relli.it
https://github.com/oscardelben/words-about-code/blob/master/2012/04/rails-edge-multiple-route-files.md
http://stackoverflow.com/questions/4930805/multiple-routing-file-in-rails-3
http://stackoverflow.com/questions/7303660/splitting-routes-file-into-multiple-files
http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/
http://markconnell.co.uk/posts/2010/02/rails-3-routing-examples
http://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/
http://accentuate.me/blog/?p=12
http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/
http://www.railsdispatch.com/posts/rails-routing
http://intridea.com/posts/use-lambdas-for-rails3-route-constraints
http://robots.thoughtbot.com/post/22605580334/constrain-yourself
https://github.com/mtrpcic/js-routes
http://stackoverflow.com/questions/341143/can-rails-routing-helpers-i-e-mymodel-pathmodel-be-used-in-models
http://stackoverflow.com/questions/3011834/uninitialized-content-when-trying-to-include-actioncontrollerurlwriter-in-mode
http://honoluluhacker.com/2011/02/05/using-rails-3-helpers-and-routes-in-the-console-or-a-rake-task/
http://webcache.googleusercontent.com/search?q=cache:http://railsguts.com/routing_inside_out.html
http://asciicasts.com/episodes/231-routing-walkthrough
http://asciicasts.com/episodes/232-routing-walkthrough-part-2
Code:
https://github.com/silviorelli/rails_routes_off_the_tracks
mercoledì 23 maggio 12