Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6646

Show
Ignore:
Timestamp:
05/01/07 04:48:48 (2 years ago)
Author:
david
Message:

BACKWARDS INCOMPATIBLE: Changed the finder API to be more extensible with :params and more strict usage of scopes [DHH] Added find-one with symbol [DHH]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activeresource/CHANGELOG

    r6625 r6646  
    11*SVN* 
    22 
    3 * Add support for setting custom headers per ActiveResource model [Rick] 
     3* Added find-one with symbol [DHH]. Example: Person.find(:one, :from => :leader) # => GET /people/leader.xml 
     4 
     5* BACKWARDS INCOMPATIBLE: Changed the finder API to be more extensible with :params and more strict usage of scopes [DHH]. Changes: 
     6 
     7    Person.find(:all, :title => "CEO")      ...becomes: Person.find(:all, :params => { :title => "CEO" }) 
     8    Person.find(:managers)                  ...becomes: Person.find(:all, :from => :managers) 
     9    Person.find("/companies/1/manager.xml") ...becomes: Person.find(:one, :from => "/companies/1/manager.xml") 
     10 
     11* Add support for setting custom headers per Active Resource model [Rick] 
    412 
    513  class Project 
  • trunk/activeresource/lib/active_resource/base.rb

    r6625 r6646  
    118118 
    119119      # Core method for finding resources.  Used similarly to Active Record's find method. 
    120       #  Person.find(1)                                        # => GET /people/1.xml 
    121       #  Person.find(:all)                                     # => GET /people.xml 
    122       #  Person.find(:all, :title => "CEO")                    # => GET /people.xml?title=CEO 
    123       #  Person.find(:managers)                                # => GET /people/managers.xml 
    124       #  Person.find(:all, :from => "/companies/1/people.xml") # => GET /companies/1/people.xml 
    125       #  Person.find("/companies/1/manager.xml")               # => GET /companies/1/manager.xml 
    126       #  StreetAddress.find(1, :person_id => 1)                # => GET /people/1/street_addresses/1.xml 
     120      # 
     121      #   Person.find(1)                                         # => GET /people/1.xml 
     122      #   Person.find(:all)                                      # => GET /people.xml 
     123      #   Person.find(:all, :params => { :title => "CEO" })      # => GET /people.xml?title=CEO 
     124      #   Person.find(:all, :from => :managers)                  # => GET /people/managers.xml 
     125      #   Person.find(:all, :from => "/companies/1/people.xml")  # => GET /companies/1/people.xml 
     126      #   Person.find(:one, :from => :leader)                    # => GET /people/leader.xml 
     127      #   Person.find(:one, :from => "/companies/1/manager.xml") # => GET /companies/1/manager.xml 
     128      #   StreetAddress.find(1, :params => { :person_id => 1 })  # => GET /people/1/street_addresses/1.xml 
    127129      def find(*arguments) 
    128130        scope   = arguments.slice!(0) 
     
    132134          when :all   then find_every(options) 
    133135          when :first then find_every(options).first 
    134           when Symbol then instantiate_collection(get(scope, options)
     136          when :one   then find_one(options
    135137          else             find_single(scope, options) 
    136138        end 
     
    149151 
    150152      private 
    151         # Find every resource. 
     153        # Find every resource 
    152154        def find_every(options) 
    153           from = options.delete(:from) 
    154           prefix_options, query_options = split_options(options) 
    155           from ||= collection_path(prefix_options, query_options) 
    156  
    157           instantiate_collection(connection.get(from, headers) || []) 
     155          case from = options.delete(:from) 
     156          when Symbol 
     157            instantiate_collection(get(from, options[:params])) 
     158          when String 
     159            path = "#{from}#{query_string(options[:params])}" 
     160            instantiate_collection(connection.get(path, headers) || []) 
     161          else 
     162            prefix_options, query_options = split_options(options[:params]) 
     163            path = collection_path(prefix_options, query_options) 
     164            instantiate_collection(connection.get(path, headers) || []) 
     165          end 
     166        end 
     167         
     168        # Find a single resource from a one-off URL 
     169        def find_one(options) 
     170          case from = options[:from] 
     171          when Symbol 
     172            instantiate_record(get(from, options[:params])) 
     173          when String 
     174            path = "#{from}#{query_string(options[:params])}" 
     175            instantiate_record(connection.get(path, headers)) 
     176          end 
     177        end 
     178 
     179        # Find a single resource from the default URL 
     180        def find_single(scope, options) 
     181          prefix_options, query_options = split_options(options[:params]) 
     182          path = element_path(scope, prefix_options, query_options) 
     183          instantiate_record(connection.get(path, headers), prefix_options) 
    158184        end 
    159185         
    160186        def instantiate_collection(collection, prefix_options = {}) 
    161           collection.collect! do |element| 
    162             returning new(element) do |resource| 
    163               resource.prefix_options = prefix_options 
    164             end 
    165           end 
    166         end 
    167  
    168         # Find a single resource. 
    169         #  { :person => person1 } 
    170         def find_single(scope, options) 
    171           prefix_options, query_options = split_options(options) 
    172           from = scope.to_s.include?("/") ? scope : element_path(scope, prefix_options, query_options) 
    173  
    174           returning new(connection.get(from, headers)) do |resource| 
     187          collection.collect! { |record| instantiate_record(record, prefix_options) } 
     188        end 
     189 
     190        def instantiate_record(record, prefix_options = {}) 
     191          returning new(record) do |resource| 
    175192            resource.prefix_options = prefix_options 
    176193          end 
    177194        end 
     195 
    178196 
    179197        # Accepts a URI and creates the site URI from that. 
     
    189207        # Builds the query string for the request. 
    190208        def query_string(options) 
    191           "?#{options.to_query}" unless options.empty?  
     209          "?#{options.to_query}" unless options.nil? || options.empty?  
    192210        end 
    193211 
     
    195213        # and the other containing the leftovers. 
    196214        def split_options(options = {}) 
    197           prefix_options = {}; query_options = {} 
    198           options.each do |key, value| 
     215          prefix_options, query_options = {}, {} 
     216 
     217          (options || {}).each do |key, value| 
    199218            (prefix_parameters.include?(key) ? prefix_options : query_options)[key] = value 
    200219          end 
    201           [prefix_options, query_options] 
     220 
     221          [ prefix_options, query_options ] 
    202222        end 
    203223    end 
     
    264284    # Evaluates to <tt>true</tt> if this resource is found. 
    265285    def exists? 
    266       !new? && self.class.exists?(id, prefix_options) 
     286      !new? && self.class.exists?(id, :params => prefix_options) 
    267287    end 
    268288 
  • trunk/activeresource/test/base_test.rb

    r6625 r6646  
    181181 
    182182  def test_find_by_id_with_custom_prefix 
    183     addy = StreetAddress.find(1, :person_id => 1
     183    addy = StreetAddress.find(1, :params => { :person_id => 1 }
    184184    assert_kind_of StreetAddress, addy 
    185185    assert_equal '12345 Street', addy.street 
     
    220220  end 
    221221 
     222  def test_find_all_by_from_with_options 
     223    ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, "<people>#{@david}</people>" } 
     224   
     225    people = Person.find(:all, :from => "/companies/1/people.xml") 
     226    assert_equal 1, people.size 
     227    assert_equal "David", people.first.name 
     228  end 
     229 
     230  def test_find_all_by_symbol_from 
     231    ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, "<people>#{@david}</people>" } 
     232   
     233    people = Person.find(:all, :from => :managers) 
     234    assert_equal 1, people.size 
     235    assert_equal "David", people.first.name 
     236  end 
     237 
    222238  def test_find_single_by_from 
    223239    ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david } 
    224240 
    225     david = Person.find("/companies/1/manager.xml") 
     241    david = Person.find(:one, :from => "/companies/1/manager.xml") 
     242    assert_equal "David", david.name 
     243  end 
     244 
     245  def test_find_single_by_symbol_from 
     246    ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david } 
     247 
     248    david = Person.find(:one, :from => :leader) 
    226249    assert_equal "David", david.name 
    227250  end 
     
    250273  # Test that loading a resource preserves its prefix_options. 
    251274  def test_load_preserves_prefix_options 
    252     address = StreetAddress.find(1, :person_id => 1
     275    address = StreetAddress.find(1, :params => { :person_id => 1 }
    253276    ryan = Person.new(:id => 1, :name => 'Ryan', :address => address) 
    254277    assert_equal address.prefix_options, ryan.address.prefix_options 
     
    280303 
    281304  def test_update_with_custom_prefix 
    282     addy = StreetAddress.find(1, :person_id => 1
     305    addy = StreetAddress.find(1, :params => { :person_id => 1 }
    283306    addy.street = "54321 Street" 
    284307    assert_kind_of StreetAddress, addy 
     
    304327 
    305328  def test_destroy_with_custom_prefix 
    306     assert StreetAddress.find(1, :person_id => 1).destroy 
     329    assert StreetAddress.find(1, :params => { :person_id => 1 }).destroy 
    307330    ActiveResource::HttpMock.respond_to do |mock| 
    308331      mock.get "/people/1/addresses/1.xml", {}, nil, 404 
    309332    end 
    310     assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :person_id => 1) } 
     333    assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) } 
    311334  end 
    312335 
     
    324347      mock.get "/people/1/addresses/1.xml", {}, nil, 404 
    325348    end 
    326     assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :person_id => 1) } 
     349    assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) } 
    327350  end 
    328351 
     
    339362 
    340363    # Nested class method. 
    341     assert StreetAddress.exists?(1, :person_id => 1
    342     assert !StreetAddress.exists?(1, :person_id => 2
    343     assert !StreetAddress.exists?(2, :person_id => 1
     364    assert StreetAddress.exists?(1, :params => { :person_id => 1 }
     365    assert !StreetAddress.exists?(1, :params => { :person_id => 2 }
     366    assert !StreetAddress.exists?(2, :params => { :person_id => 1 }
    344367 
    345368    # Nested instance method. 
    346     assert StreetAddress.find(1, :person_id => 1).exists? 
     369    assert StreetAddress.find(1, :params => { :person_id => 1 }).exists? 
    347370    assert !StreetAddress.new({:id => 1, :person_id => 2}).exists? 
    348371    assert !StreetAddress.new({:id => 2, :person_id => 1}).exists? 
  • trunk/activeresource/test/base/custom_methods_test.rb

    r6585 r6646  
    6464     
    6565    # With nested resources 
    66     assert_equal StreetAddress.find(1, :person_id => 1).get(:deep), 
     66    assert_equal StreetAddress.find(1, :params => { :person_id => 1 }).get(:deep), 
    6767                  { "id" => 1, "street" => '12345 Street', "zip" => "27519" } 
    6868    assert_equal ActiveResource::Response.new("", 204, {}), 
    69                    StreetAddress.find(1, :person_id => 1).put(:normalize_phone, :locale => 'US') 
     69                   StreetAddress.find(1, :params => { :person_id => 1 }).put(:normalize_phone, :locale => 'US') 
    7070  end 
    7171   
     
    8383   
    8484  def test_find_custom_resources 
    85     assert_equal 'Matz', Person.find(:managers).first.name 
     85    assert_equal 'Matz', Person.find(:all, :from => :managers).first.name 
    8686  end 
    8787end