Search code examples
ruby-on-railsrubyactiveresource

What are the consequences of overriding Array.to_param within an ActiveResource based plugin


An active_resource based class:

Contact.search(:email => ['bar@foo.com','foo@bar.com'])

would produce this:

?email[]=bar@foo.com&email[]=foo@bar.com

The specific API that I'm working with requires this:

?email=bar@foo.com&email=foo@bar.com

So playing around I have found that:

ActiveResouce calls:

# Find every resource
find_every(options)

which calls:

  # Builds the query string for the request.
  def query_string(options)
    "?#{options.to_query}" unless options.nil? || options.empty?
  end

So if I update:

class Array
  # Converts an array into a string suitable for use as a URL query string,
  # using the given +key+ as the param name.
  #
  # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
  def to_query(key)
    prefix = "#{key}[]"
    collect { |value| value.to_query(prefix) }.join '&'
  end
end

to this:

class Array
  # Converts an array into a string suitable for use as a URL query string,
  # using the given +key+ as the param name.
  #
  # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
  def to_query(key)
    prefix = "#{key}"
    collect { |value| value.to_query(prefix) }.join '&'
  end
end

it works!! however I'm not particularly happy redefining Array.to_param because this may have unforeseen issues, especially as this plug in needs to work within rails.

Is there another way I can patch only my version?


Solution

  • As this behaviour is standard through the API I'm using I was able to add this patch to my ActiveRecord::Base class.

      def query_string(options)
        begin
          super(options).gsub('%5B%5D','')
        rescue
        end
      end
    

    Thanks to Beerlington for pointing me in the right direction for this.