Changeset 1672

Show
Ignore:
Timestamp:
03/01/08 19:56:10 (3 months ago)
Author:
pdcawley
Message:

More work on UrlPolicy?. url_for(Article), url_for(an_article.comments) now give good answers...

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/models/url_policy.rb

    r1670 r1672  
    2929 
    3030class UrlPolicy 
     31  class CollectionProxy 
     32    attr_reader :parent 
     33    def initialize(parent) 
     34      @parent = parent 
     35    end 
     36 
     37    def new_record? 
     38      false 
     39    end 
     40 
     41    def characteristic_hash 
     42      {} 
     43    end 
     44  end 
     45 
    3146  include ::Singleton 
    3247  include ::ActionController::UrlWriter 
     
    4459 
    4560  def url_for_with_policy(*args) 
    46     with_options(:only_path => true) do |o| 
    47       case args.first 
    48       when nil 
    49         raise ArgumentError, "Argument cannot be nil" 
    50       when ActiveRecord::Base 
    51         o.url_for_object(*args) 
     61    options = (Hash === args.last) ? args.pop.symbolize_keys : {} 
     62    with_options(options.reverse_merge(:only_path => true)) do |o| 
     63      case args.size 
     64        when 0 
     65        o.url_for_without_policy() 
     66      when 2 
     67        o.url_for_chain(*args) 
    5268      else 
    53         o.url_for_without_policy(*args) 
     69        if  association_collection? args.first 
     70          return o.url_for_collection(*args) 
     71        end 
     72 
     73        case args.first 
     74        when Class 
     75          return o.url_for_class(*args) 
     76        when ActiveRecord::Base, CollectionProxy 
     77          return o.url_for_object(*args) 
     78        else 
     79          return o.url_for_without_policy(*args) 
     80        end 
    5481      end 
    5582    end 
     
    5885  alias_method_chain :url_for, :policy 
    5986 
     87 
     88  def url_for_class(klass, opts = {}) 
     89    url_for opts.reverse_merge(:controller => klass.name.pluralize.underscore) 
     90  end 
     91 
    6092  def url_for_object(object, opts = {}) 
    61     with_options(opts) { |o| 
    62       o.url_for(params_for(object)); 
    63     } 
     93    suggested_params = params_for(object) 
     94    if opts.has_key? :controller 
     95      suggested_params.delete(:action) 
     96    end 
     97 
     98    url_for(suggested_params.merge(opts)) 
     99  end 
     100 
     101  def association_collection?(object) 
     102    object.respond_to?(:proxy_reflection) && object.respond_to?(:count) 
     103  end 
     104 
     105  def url_for_collection(collection, opts = {}) 
     106    owner = collection.proxy_owner; 
     107    controller = collection.proxy_reflection.klass.name.pluralize.underscore 
     108    url_for(CollectionProxy.new(owner), 
     109            opts.merge(:controller => controller)) 
     110  end 
     111 
     112  def url_for_chain(parent, klass, opts = { }) 
     113    url_for(CollectionProxy.new(parent), 
     114            opts.merge(:controller => klass.name.pluralize.underscore)) 
    64115  end 
    65116 
     
    85136  def characteristic_hash(resource) 
    86137    raise ArgumentErrror, "#{resource}.new_record? must not be true" if resource.new_record? 
     138 
     139    if resource.respond_to? :characteristic_hash 
     140      return resource.characteristic_hash 
     141    end 
    87142 
    88143    class_specific_method_name = "characteristic_#{resource.class.name.underscore}_hash" 
  • trunk/spec/models/url_policy_spec.rb

    r1670 r1672  
    1919    comment.save(false) 
    2020    UrlPolicy.instance.url_for(comment).should == "/articles/2004/06/01/article-3/comments/#{comment.guid}" 
     21  end 
     22 
     23  it "#url_for(article3.comments).should == /articles/2004/06/01/article-3/comments" do 
     24    article = contents(:article3) 
     25    comment = article.comments.build(:author => 'Piers Cawley', :body => "body") 
     26    comment.save(false) 
     27    UrlPolicy.instance.url_for(article.comments).should == 
     28      "/articles/2004/06/01/article-3/comments" 
     29  end 
     30 
     31  it "#url_for(article3, Comment) should be /articles/2004/06/01/article-3/comments" do 
     32    UrlPolicy.instance.url_for(contents(:article3), Comment).should == 
     33      "/articles/2004/06/01/article-3/comments" 
     34  end 
     35 
     36  it "#url_for Article should be /" do 
     37    UrlPolicy.instance.url_for(Article).should == '/' 
    2138  end 
    2239