Today I had to make sure that a url wasn’t containing a certain parameter, and if it was I needed to clean it form the params.
Let’s assume a resource like
* RESOURCE
* url
When saving that resource I need to make sure that the a param ‘user_ref’ is not present from the url. This param can or cannot have values.
So we start with a simple test
require 'spec_helper'
describe Resource do
describe 'cleaning user_ref param' do
before do
@empty_param = FactoryGirl.create(:resource, :url => "http://google.com?param1=1&clickref=¶m3")
@full_param = FactoryGirl.create(:resource, :url => "http://google.com?param1=1&clickref=remove-me¶m3")
@clean_url = FactoryGirl.create(:resource, :url => "http://google.com?param1=1")
end
it "should remove empty click ref params and keep other params" do
@empty_param.url.should eql("http://google.com?param1=1¶m3")
end
it "should remove full click ref params and keep other params" do
@full_param.url.should eql("http://google.com?param1=1¶m3")
end
it "should still save url without click ref params and keep other params" do
@clean_url.url.should eql("http://google.com?param1=1")
end
end
end
After testing different Regexps (and I have to admin I’m not a master of them, so maybe the solution is somewhere else), I finally found Addressable Gem and everything became easy again.
EDIT: Theo Cushion sent me a better cleaner solution via email, please check the bottom of the post
In the Resource model I have
class Resource < ActiveRecord::Base
....
before_save :clean_clickref
....
protected
def clean_clickref
if self.url
require 'addressable/uri'
uri = Addressable::URI.parse(self.url)
params = uri.query_values
if params
uri.query_values = params.except('clickref')
self.url = uri.to_s
end
end
end
end
EDIT: This is Theo Cushion’s solution, using the url setter. Way nicer, and we don’t need the :before_save
class Resource < ActiveRecord::Base
....
def url=(value)
require 'addressable/uri'
result = if value.is_a? String
uri = Addressable::URI.parse value
uri.query_values = uri.query_values.except( 'clickref' ) if uri.query_values
uri.to_s
else
nil
end
write_attribute :url, result
end
....
end
This is easy enough and readable enough and make the tests pass, time for the next feature!