merb pluming - the router

33
Merb Plumbing The Router

Upload: carllerche

Post on 18-May-2015

6.118 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Merb Pluming - The Router

Merb PlumbingThe Router

Page 2: Merb Pluming - The Router

Who am I?

Page 3: Merb Pluming - The Router
Page 4: Merb Pluming - The Router

Some simple routes

Matching

Merb::Router.prepare do match("/signup").to( :controller => "users", :action => "new" ).name(:signup) end

Generating

url(:signup) => /signup

Page 5: Merb Pluming - The Router

Routes with variables

Matching

match("/articles/:year/:month/:day/:title").to( :controller => "articles", :action => "show" ).name(:article)

Generating

url(:article, :year => 2008, :month => 07, :day => 22, :title => "Awesomeness")

/articles/2008/07/22/Awesomeness

Page 6: Merb Pluming - The Router

Routes with conditions

Matching

match("/articles") do with(:controller => "articles") do match("/:title", :title => /[a-z]+/). to(:action => "with_title") match("/:id").to(:action => "with_id") end end

/articles/Hello_world => with_title /articles/123 => with_id

Page 7: Merb Pluming - The Router

More conditions

Matching

Merb::Router.prepare do match(:domain => "blogofawesomeness.com") do match("/the-daily-awesome", :method => "get"). to(:articles) # Any other route... end end

Page 8: Merb Pluming - The Router

The subdomain problem

match(:subdomain => /(.*)/). to(:account => ":subdomain[1]") do # application routes here... end

Page 9: Merb Pluming - The Router

Optional path segments

Matching

match("/articles(/:year(/:month(/:day)))/:title"). to(:controller => "articles", :action => "show"). name(:article)

Generating

/articles/Hello => { :title => “Hello” }

/articles/2008/07/Hello => { :year => 2008, :month => “07” :title => “Hello” }

Page 10: Merb Pluming - The Router

... and generation still works!

url(:article, :title => "Hello")

url(:article, :year => "2008", :title => "Hello")

url(:article, :year => "2008", :month => "07", :title => "Hello")

url(:article, :year => "2008", :month => "07", :day => "22", :title => "Hello")

Page 11: Merb Pluming - The Router

Getting Fancy

Matching

match("(:pref)/:file(.:format)", :pref => ".*"). to(:controller => "cms").name(:page)

/hi => { :file => “hi” } /hi.xml => { :file => “hi”, :format => “xml”} /path/to/hi => { :pref => “/path/to”, :file => “hi }

Page 12: Merb Pluming - The Router

And you can still generate it url(:page, :file => "hi")

/hi

url(:page, :pref => "/path/to", :file => "hi")

/path/to/hi

url(:page, :pref => "/hello", :file => "world", :format => "mp3")

/hello/world.mp3

Page 13: Merb Pluming - The Router

The default route

def default_route(params = {}, &block) match("/:controller(/:action(/:id))(.:format)"). to(params, &block).name(:default) end

Page 14: Merb Pluming - The Router

AWESOME!

Page 15: Merb Pluming - The Router

Resource routes

Matching

resources :articles

/articles GET => index /articles POST => create /articles/new GET => new /articles/:id GET => show /articles/:id PUT => update /articles/:id DELETE => destroy /articles/:id/edit GET => edit /articles/:id/delete GET => delete

Page 16: Merb Pluming - The Router

and you can nest them

Matching

resources :articles do resources :comments end

Generating

link_to "view comment", url(:article_comment, comment.article_id, comment.id)

Page 17: Merb Pluming - The Router

Nested multiple times

resources :articles do resources :comments end resources :songs do resources :comments end resources :photos do resources :comments end

Page 18: Merb Pluming - The Router

and... generating?

link_to "view comment", comment.commentable.is_a?(Article) ? url(:article_comment, comment.commentable.id, comment.id) : comment.commentable.is_a?(Song) ? url(:song_comment, comment.commentable.id, comment.id) : url(:photo_comment, comment.commentable.id, comment.id)

wha...?

Page 19: Merb Pluming - The Router

Nah... how about this?

link_to "view comment", resource(comment.commentable, comment)

Page 20: Merb Pluming - The Router

Some more examples resources :users do

resources :comments end

Generating

resource(@user) resource(@user, :comments) vs. vs. url(:user, @user) url(:user_comments, @user)

resource @user, @comment vs. url(:user_comment, @user, @comment)

Page 21: Merb Pluming - The Router

Oh yeah...

match("/:project") do resources :tasks end

- While currently at /awesome/tasks

resource(@task) => /awesome/tasks/123

resource(@task, :project => "woot") => /woot/tasks/123

Page 22: Merb Pluming - The Router

AWESOME!

Page 23: Merb Pluming - The Router

Friendly URLs

Matching resources :users, :identify => :name

Generating

resource(@user) # => /users/carl

Page 24: Merb Pluming - The Router

It works as a block too

Matching

identify(Article=>:permalink, User=>:login) do resources :users do resources :articles end end

Generating

resource(@user, @article)

/users/carl/articles/hello-world

Page 25: Merb Pluming - The Router

AWESOME!

Page 26: Merb Pluming - The Router

Redirecting legacy URLs

Old: /articles/123-hello-world

New: /articles/Hello_world

Page 27: Merb Pluming - The Router

Handle it in the controller?

match("/articles/:id"). to(:controller => "articles", :action => "show")

Page 28: Merb Pluming - The Router

Try to do it with Regexps?

match("/articles/:id", :id => /^\d+-/). to(:controller => "articles", :action => "legacy")

match("/articles/:url"). to(:controller => "articles", :action => "show")

Page 29: Merb Pluming - The Router

Or, add your own logic!

match("/articles/:url").defer_to do |request, params| if article = Article.first(:url => params[:url]) params.merge(:article => article) elsif article = Article.first(:id => params[:url]) redirect url(:article, article.url) else false end end

Page 30: Merb Pluming - The Router

Authentication works too

match("/secret").defer_to do |request, params| if request.session.authenticated? params end end

Page 31: Merb Pluming - The Router

Works great for plugins

def protect(&block) protection = Proc.new do |request, params| if request.session.authenticated? params else redirect "/login" end end

defer(protection, &block) end

Page 32: Merb Pluming - The Router

Awesome!

protect.match("/admin") do # ... admin routes here end

Page 33: Merb Pluming - The Router

Thank you(Awesome!)