28
@silviorelli Rails Routes off the tracks Unpopular (and/or improper) useful hacks for the Rails routes mercoledì 23 maggio 12

Rails Routes off the tracks

  • Upload
    silvio

  • View
    6.559

  • Download
    0

Embed Size (px)

DESCRIPTION

Slides for my talk at Florence On Ruby

Citation preview

Page 1: Rails Routes off the tracks

@silviorelli

Rails Routes off the tracksUnpopular (and/or improper) useful hacks for the Rails routes

mercoledì 23 maggio 12

Page 2: Rails Routes off the tracks

Less known routesBasic routes

mercoledì 23 maggio 12

Page 3: Rails Routes off the tracks

@silviorelli

Basic routes summary # 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'

part I

mercoledì 23 maggio 12

Page 4: Rails Routes off the tracks

@silviorelli

Basic routes summary # 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

part II

mercoledì 23 maggio 12

Page 5: Rails Routes off the tracks

@silviorelli

Basic routes summary # 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' }

part III

mercoledì 23 maggio 12

Page 6: Rails Routes off the tracks

@silviorelli

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'

mercoledì 23 maggio 12

Page 7: Rails Routes off the tracks

@silviorelli

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 :descriptionsend

# Default generic Rails 3 routematch '/:controller(/:action(/:id))'

mercoledì 23 maggio 12

Page 8: Rails Routes off the tracks

Less known routes

mercoledì 23 maggio 12

Page 9: Rails Routes off the tracks

@silviorelli

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/}

mercoledì 23 maggio 12

Page 10: Rails Routes off the tracks

@silviorelli

More on constraints# Arbitrary constraintconstraints(:ip => /127.0.0.1/) do match '/questions', :to => redirect('http://www.stackoverflow.com/')end

# Object-based constraintclass IpRestrictor def self.matches?(request) request.ip =~ /127.0.0.1/ endend

constraints IpRestrictor do match '/questions', :to => redirect('http://www.stackoverflow.com/')end

mercoledì 23 maggio 12

Page 11: Rails Routes off the tracks

@silviorelli

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

mercoledì 23 maggio 12

Page 12: Rails Routes off the tracks

@silviorelli

endpoints

Text

Rack provides a minimal interface between webservers supporting Ruby and Ruby frameworks.

class MySinatraBlogApp < Sinatra::Base get "/blog/archives" do "my old posts" endend

match "/blog" => MySinatraBlogApp, :anchor => false

mount MySinatraBlogApp, :at => "/blog"# or simplymount MySinatraBlogApp => "/blog"

part I

mercoledì 23 maggio 12

Page 13: Rails Routes off the tracks

@silviorelli

Rack endpoints

Text

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.rbclass LoggedInConstraint < Struct.new(:value) def matches?(request) request.cookies.key?("auth_token") == value endend

part II

mercoledì 23 maggio 12

Page 14: Rails Routes off the tracks

@silviorelli

Splitted routes file

Text

# In config/application.rb config.paths["config/routes"] << Rails.root.join('config/routes/api_routes.rb')

# In config/routes/api_routes.rbSandbox::Application.routes.draw do constraints(:subdomain => 'api') do resources :recipes end end

### Coming in Rails 4 ###

# config/routes.rbdraw :admin

# config/routes/admin.rbnamespace :admin do resources :postsend

mercoledì 23 maggio 12

Page 15: Rails Routes off the tracks

Less known routesOff Track routes

mercoledì 23 maggio 12

Page 16: Rails Routes off the tracks

@silviorelli

Routes in Models

mercoledì 23 maggio 12

Page 17: Rails Routes off the tracks

@silviorelli

Routes in Models

R.I.P.MVC

Encapsulation

mercoledì 23 maggio 12

Page 18: Rails Routes off the tracks

@silviorelli

Routes helpers in Modelsclass Post < ActiveRecord::Base attr_accessible :content, :name, :title

def put_routes posts_path end

end

1.9.3p194 :001 > Post.first.put_routesPost Load (0.3ms) SELECT `posts`.* FROM `posts` LIMIT 1NameError: undefined local variable or method `posts_path' for #<Post:0x007ff1a17f4e60>

part I

mercoledì 23 maggio 12

Page 19: Rails Routes off the tracks

@silviorelli

Routes helpers in Modelsclass Post < ActiveRecord::Base attr_accessible :content, :name, :title

include Rails.application.routes.url_helpers default_url_options[:host] = 'example.com'

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 => "/posts"

1.9.3p194 :002 > Post.first.put_instance_route Post Load (0.6ms) SELECT `posts`.* FROM `posts` LIMIT 1 => "http://example.com/posts/1"

def put_instance_route url_for(self) end

include ActionDispatch::Routing::UrlFor

part II

mercoledì 23 maggio 12

Page 20: Rails Routes off the tracks

@silviorelli

Routes helpers in Modelsclass Post < ActiveRecord::Base attr_accessible :content, :name, :title include ActionDispatch::Routing::UrlFor include Rails.application.routes.url_helpers default_url_options[:host] = 'example.com' def self.put_routes Rails.application.routes.url_helpers.posts_path end end

1.9.3p194 :001 > Post.put_routesNameError: undefined local variable or method `posts_path' for #<Class:0x007fcb9b1260d8>

class Post < ActiveRecord::Base attr_accessible :content, :name, :title include ActionDispatch::Routing::UrlFor include Rails.application.routes.url_helpers default_url_options[:host] = 'example.com' def self.put_routes posts_path end end

1.9.3p194 :001 > Post.put_routes => "/posts"

part III

mercoledì 23 maggio 12

Page 21: Rails Routes off the tracks

@silviorelli

Routes helpers in console

1.9.3p194 :001 > posts_pathNameError: 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"

mercoledì 23 maggio 12

Page 22: Rails Routes off the tracks

@silviorelli

Routes helpers in Rake Tasknamespace :example do desc "Example of routes helper in rake task" task :posts => :environment do puts "items_path = #{posts_path}" endend

@Pade ➜ rake example:postsrake aborted!undefined local variable or method `posts_path' for main:Object

namespace :example do desc "Example of routes helper in rake task" task :posts => :environment do include Rails.application.routes.url_helpers puts "items_path = #{posts_path}" endend

@Pade ➜ rake example:postsitems_path = /posts

mercoledì 23 maggio 12

Page 23: Rails Routes off the tracks

Less known routesOff Track routes Goodies

mercoledì 23 maggio 12

Page 24: Rails Routes off the tracks

@silviorelli

Routes in Javascriptsjs:routeshttps://github.com/mtrpcic/js-routes

# First, place the js.rake file in /lib/tasksyour_app/lib/tasks/js.rake# 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# You can specify your own filename like so:rake js:routes[custom_name.js]

$.ajax({ url: "/post/" + post_id; method: 'PUT', data:{ x: post_x, y: post_y }});

$.ajax({ url: post_path({id: post_id}) method: 'PUT', data:{ x: post_x, y: post_y }});

Broken on Rails >= 3.1

mercoledì 23 maggio 12

Page 25: Rails Routes off the tracks

@silviorelli

Routes list in the browsersexant gemhttps://github.com/schneems/sextant

Visit /rails/routes in the browser

mercoledì 23 maggio 12

Page 26: Rails Routes off the tracks

@silviorelli

i18n translable routesrails-translate-routes gemhttps://github.com/francesc/rails-translate-routes

# In config/locales/routes.ymlen: # you can leave empty locales, for example the default onees: 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"}

part I

mercoledì 23 maggio 12

Page 27: Rails Routes off the tracks

@silviorelli

i18n translable routesi18n_routing gemhttps://github.com/kwi/i18n_routing

# In config/routes.rb :localized do resources :usersend

ruby-1.8.7-p249 > I18n.locale = :en => :en ruby-1.8.7-p249 > app.users_path => "/users" ruby-1.8.7-p249 > I18n.locale = :fr => :fr ruby-1.8.7-p249 > app.users_path => "/utilisateurs"

part II

# In config/locales/fr.ymlfr: resources: users: 'utilisateurs'

mercoledì 23 maggio 12

Page 28: Rails Routes off the tracks

Less known routesRails Routes off the tracks23 May 2012

Silvio [email protected]

by

References:http://guides.rubyonrails.org/routing.htmlhttp://api.rubyonrails.org/classes/ActionDispatch/Routing.htmlhttps://github.com/oscardelben/words-about-code/blob/master/2012/04/rails-edge-multiple-route-files.mdhttp://stackoverflow.com/questions/4930805/multiple-routing-file-in-rails-3http://stackoverflow.com/questions/7303660/splitting-routes-file-into-multiple-fileshttp://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/http://markconnell.co.uk/posts/2010/02/rails-3-routing-exampleshttp://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/http://accentuate.me/blog/?p=12http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/http://www.railsdispatch.com/posts/rails-routinghttp://intridea.com/posts/use-lambdas-for-rails3-route-constraintshttp://robots.thoughtbot.com/post/22605580334/constrain-yourselfhttps://github.com/mtrpcic/js-routeshttp://stackoverflow.com/questions/341143/can-rails-routing-helpers-i-e-mymodel-pathmodel-be-used-in-modelshttp://stackoverflow.com/questions/3011834/uninitialized-content-when-trying-to-include-actioncontrollerurlwriter-in-modehttp://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.htmlhttp://asciicasts.com/episodes/231-routing-walkthroughhttp://asciicasts.com/episodes/232-routing-walkthrough-part-2

Code:https://github.com/silviorelli/rails_routes_off_the_tracks

mercoledì 23 maggio 12