diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2006-12-29 01:18:09 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2006-12-29 01:18:09 +0000 |
commit | 4e57ac35443759778bd6c1fcfd29e8bd85e9d15d (patch) | |
tree | d1414e69479fcc0807d4e57f3c86b624f1981ebe | |
parent | f9f84d9f6dea72cae4fc8e31448df408caccbd59 (diff) | |
download | rails-4e57ac35443759778bd6c1fcfd29e8bd85e9d15d.tar.gz rails-4e57ac35443759778bd6c1fcfd29e8bd85e9d15d.tar.bz2 rails-4e57ac35443759778bd6c1fcfd29e8bd85e9d15d.zip |
Query string support. Closes #6855.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5804 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | activeresource/CHANGELOG | 4 | ||||
-rw-r--r-- | activeresource/lib/active_resource/base.rb | 44 | ||||
-rw-r--r-- | activeresource/test/base_test.rb | 22 |
3 files changed, 64 insertions, 6 deletions
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG index a9bb625781..3a2d70c387 100644 --- a/activeresource/CHANGELOG +++ b/activeresource/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Query string support. [untext, Jeremy Kemper] + # GET /forums/1/topics.xml?sort=created_at + Topic.find(:all, :forum_id => 1, :sort => 'created_at') + * Base#==, eql?, and hash methods. == returns true if its argument is identical to self or if it's an instance of the same class, is not new?, and has the same id. eql? is an alias for ==. hash delegates to id. [Jeremy Kemper] * Allow subclassed resources to share the site info [Rick, Jeremy Kemper] diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index a8918b1eee..8c4d82c421 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -1,4 +1,6 @@ require 'active_resource/connection' +require 'cgi' +require 'set' module ActiveResource class Base @@ -29,7 +31,7 @@ module ActiveResource attr_accessor_with_default(:element_name) { to_s.underscore } attr_accessor_with_default(:collection_name) { element_name.pluralize } attr_accessor_with_default(:primary_key, 'id') - + def prefix(options={}) default = site.path default << '/' unless default[-1..-1] == '/' @@ -38,21 +40,29 @@ module ActiveResource end def prefix=(value = '/') - prefix_call = value.gsub(/:\w+/) { |s| "\#{options[#{s}]}" } - method_decl = %(def self.prefix(options={}) "#{prefix_call}" end) - eval method_decl + @prefix_parameters = Set.new + prefix_call = value.gsub(/:\w+/) do |key| + @prefix_parameters << key[1..-1].to_sym + "\#{options[#{key}]}" + end + method_decl = %(def prefix(options={}) "#{prefix_call}" end) + instance_eval method_decl, __FILE__, __LINE__ + rescue + logger.error "Couldn't set prefix: #{$!}\n #{method_decl}" + raise end + alias_method :set_prefix, :prefix= alias_method :set_element_name, :element_name= alias_method :set_collection_name, :collection_name= def element_path(id, options = {}) - "#{prefix(options)}#{collection_name}/#{id}.xml" + "#{prefix(options)}#{collection_name}/#{id}.xml#{query_string(options)}" end def collection_path(options = {}) - "#{prefix(options)}#{collection_name}.xml" + "#{prefix(options)}#{collection_name}.xml#{query_string(options)}" end alias_method :set_primary_key, :primary_key= @@ -88,6 +98,28 @@ module ActiveResource def create_site_uri_from(site) site.is_a?(URI) ? site.dup : URI.parse(site) end + + def query_string(options) + # Omit parameters which appear in the URI path. + query_params = options.reject { |key, value| @prefix_parameters.include?(key) } + + # Accumulate a list of escaped key=value pairs for the given parameters. + pairs = [] + query_params.each do |key, value| + key = CGI.escape(key.to_s) + + # a => b becomes a=b + # a => [b, c] becomes a[]=b&a[]=c + case value + when Array + value.each { |val| pairs << "#{key}[]=#{CGI.escape(val.to_s)}" } + else + pairs << "#{key}=#{CGI.escape(value.to_s)}" + end + end + + "?#{pairs * '&'}" unless pairs.empty? + end end attr_accessor :attributes diff --git a/activeresource/test/base_test.rb b/activeresource/test/base_test.rb index b036e1d346..bfc8a9fb68 100644 --- a/activeresource/test/base_test.rb +++ b/activeresource/test/base_test.rb @@ -82,14 +82,34 @@ class BaseTest < Test::Unit::TestCase assert_equal '/people.xml', Person.collection_path end + def test_collection_path_with_parameters + assert_equal '/people.xml?gender=male', Person.collection_path(:gender => 'male') + assert_equal '/people.xml?gender=false', Person.collection_path(:gender => false) + assert_equal '/people.xml?gender=', Person.collection_path(:gender => nil) + + assert_equal '/people.xml?gender=male', Person.collection_path('gender' => 'male') + assert_equal '/people.xml?student=true&gender=male', Person.collection_path(:gender => 'male', :student => true) + + assert_equal '/people.xml?name[]=bob&name[]=your+uncle%2Bme&name[]=&name[]=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false]) + end + def test_custom_element_path assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, :person_id => 1) end + def test_custom_element_path_with_parameters + assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work') + assert_equal '/people/1/addresses/1.xml?type[]=work&type[]=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time']) + end + def test_custom_collection_path assert_equal '/people/1/addresses.xml', StreetAddress.collection_path(:person_id => 1) end + def test_custom_collection_path_with_parameters + assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path(:person_id => 1, :type => 'work') + end + def test_custom_element_name assert_equal 'address', StreetAddress.element_name end @@ -108,11 +128,13 @@ class BaseTest < Test::Unit::TestCase def test_prefix assert_equal "/", Person.prefix + assert_equal Set.new, Person.instance_variable_get('@prefix_parameters') end def test_custom_prefix assert_equal '/people//', StreetAddress.prefix assert_equal '/people/1/', StreetAddress.prefix(:person_id => 1) + assert_equal [:person_id].to_set, StreetAddress.instance_variable_get('@prefix_parameters') end def test_find_by_id |