The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
DRY Up Your Url Helpers

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Matthias Georgi

Posts: 54
Nickname: georgi
Registered: Apr, 2007

Matthias Georgi is a Ruby on Rails freelancer.
DRY Up Your Url Helpers Posted: Apr 18, 2007 6:59 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Matthias Georgi.
Original Post: DRY Up Your Url Helpers
Feed Title: Matthias Georgi
Feed URL: http://feeds.feedburner.com/matthias-georgi?format=xml
Feed Description: Webdev, Gamedev and Interaction Design.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Matthias Georgi
Latest Posts From Matthias Georgi

Advertisement
This tutorial shows you how to simplify url generation in combination with RESTful resources by extending the url_for helper. This approach will also work with nested routes and other helpers like form_tag and link_to. Each resource will have its own unique url, which is generated by calling url_for(resource). First we need a simple example. We have 2 models: User and Article. For our url generation to work we have to add following code to our models:
class User
 has_many :articles

  def to_params
    {:id => permalink}
  end
end

class Article
 belongs_to :user

  def to_params
    {:user_id => user.permalink, :id => permalink}
  end
end
This is necessary for nested routes to play nicely with our url generation code. We are now able to find the parameters for each record to generate an unique URL. Our nested routes are defined in config/routes.rb:
map.resources :users do |user|
 user.resources :articles
end
And now add the following module into your lib folder and include the module in both your application controller and application helper:
module ResourceHelper

def plural_class_name(record)
 record.class.name.underscore.pluralize
end

def singular_class_name(record)
 record.class.name.underscore
end

def params_for(record)
  if record.respond_to?(:to_params)
   record.to_params
 else
   {:id => record.to_param}
 end
end

def collection_url(collection, record, options)
  if record
   params = params_for(record)
   params["#{singular_class_name(record)}_id".to_sym] = params.delete(:id)
   url_for options.merge(params).merge(:controller => collection)
 else
   url_for options.merge(:controller => collection)
 end
end

def member_url(record, options)
 url_for options.merge(params_for(record)).merge(:controller => plural_class_name(record))
end

def url_for(*args)
  if [String, Hash].any? {|type| args.first.is_a? type }
   super(*args)
 else
    if args[0].is_a?(Symbol)
     collection_url(args[0], args[1], :action => 'index')
  else
     member_url(args.first, :action => 'show')
  end
end
end

def new_url_for(collection, record=nil)
 collection_url(collection, record, :action => 'new')
end

def edit_url_for(record)
 member_url(record, :action => 'edit')
end
def path_for(*args)
  if args[0].is_a?(Symbol)
   collection_url(args[0], args[1], :action => 'index', :only_path => true)
 else
   member_url(args.first, :action => 'show', :only_path => true)
 end
end

def new_path_for(collection, record=nil)
 collection_url(collection, record, :action => 'new', :only_path => true)
end

def edit_path_for(record)
 member_url(record, :action => 'edit', :only_path => true)
end
end
So how can you use this stuff actually? It is pretty easy: just pass the record instead of the url hash and the unique url will be generated automatically. This works for helpers like url_for, form_tag or link_to. Some examples:
new_path_for(:users)          # => '/users/new'
path_for(user)                # => '/users/harald'
edit_path_for(user)           # => '/users/harald;edit'
path_for(:articles, user)     # => '/users/harald/articles'
new_path_for(:articles, user) # => '/users/harald/articles/new'
path_for(article)             # => '/users/harald/articles/article-1'
edit_path_for(article)        # => '/users/harald/articles/article-1;edit'
link_to article.title, article
form_tag :articles
form_tag article, :method => 'put'
If anybody is interested I will release this stuff as plugin. I think other helpers could benefit as well as you can pass your records around and each helper may generate the appropriate url.

Read: DRY Up Your Url Helpers

Topic: Erm, no, not really... Previous Topic   Next Topic Topic: Ruby (and Rails) Books - the essential reading list

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use