aboutsummaryrefslogtreecommitdiffstats
path: root/lib/strip_attributes
diff options
context:
space:
mode:
Diffstat (limited to 'lib/strip_attributes')
-rw-r--r--lib/strip_attributes/README.rdoc77
-rw-r--r--lib/strip_attributes/Rakefile30
-rw-r--r--lib/strip_attributes/strip_attributes.rb37
-rw-r--r--lib/strip_attributes/test/strip_attributes_test.rb90
-rw-r--r--lib/strip_attributes/test/test_helper.rb20
5 files changed, 254 insertions, 0 deletions
diff --git a/lib/strip_attributes/README.rdoc b/lib/strip_attributes/README.rdoc
new file mode 100644
index 000000000..bd55c0c1c
--- /dev/null
+++ b/lib/strip_attributes/README.rdoc
@@ -0,0 +1,77 @@
+== StripAttributes
+
+StripAttributes is a Rails plugin that automatically strips all ActiveRecord
+model attributes of leading and trailing whitespace before validation. If the
+attribute is blank, it strips the value to +nil+.
+
+It works by adding a before_validation hook to the record. By default, all
+attributes are stripped of whitespace, but <tt>:only</tt> and <tt>:except</tt>
+options can be used to limit which attributes are stripped. Both options accept
+a single attribute (<tt>:only => :field</tt>) or arrays of attributes (<tt>:except =>
+[:field1, :field2, :field3]</tt>).
+
+=== Examples
+
+ class DrunkPokerPlayer < ActiveRecord::Base
+ strip_attributes!
+ end
+
+ class SoberPokerPlayer < ActiveRecord::Base
+ strip_attributes! :except => :boxers
+ end
+
+ class ConservativePokerPlayer < ActiveRecord::Base
+ strip_attributes! :only => [:shoe, :sock, :glove]
+ end
+
+=== Installation
+
+Option 1. Use the standard Rails plugin install (assuming Rails 2.1).
+
+ ./script/plugin install git://github.com/rmm5t/strip_attributes.git
+
+Option 2. Use git submodules
+
+ git submodule add git://github.com/rmm5t/strip_attributes.git vendor/plugins/strip_attributes
+
+Option 3. Use braid[http://github.com/evilchelu/braid/tree/master] (assuming
+you're using git)
+
+ braid add --rails_plugin git://github.com/rmm5t/strip_attributes.git
+ git merge braid/track
+
+=== Other
+
+If you want to use this outside of Rails, extend StripAttributes in your
+ActiveRecord model after putting strip_attributes in your <tt>$LOAD_PATH</tt>:
+
+ require 'strip_attributes'
+ class SomeModel < ActiveRecord::Base
+ extend StripAttributes
+ strip_attributes!
+ end
+
+=== Support
+
+The StripAttributes homepage is http://stripattributes.rubyforge.org. You can
+find the StripAttributes RubyForge progject page at:
+http://rubyforge.org/projects/stripattributes
+
+StripAttributes source is hosted on GitHub[http://github.com/]:
+http://github.com/rmm5t/strip_attributes
+
+Feel free to submit suggestions or feature requests. If you send a patch,
+remember to update the corresponding unit tests. In fact, I prefer new features
+to be submitted in the form of new unit tests.
+
+=== Credits
+
+The idea was triggered by the information at
+http://wiki.rubyonrails.org/rails/pages/HowToStripWhitespaceFromModelFields
+but was modified from the original to include more idiomatic ruby and rails
+support.
+
+=== License
+
+Copyright (c) 2007-2008 Ryan McGeary released under the MIT license
+http://en.wikipedia.org/wiki/MIT_License \ No newline at end of file
diff --git a/lib/strip_attributes/Rakefile b/lib/strip_attributes/Rakefile
new file mode 100644
index 000000000..05b0c14ad
--- /dev/null
+++ b/lib/strip_attributes/Rakefile
@@ -0,0 +1,30 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the stripattributes plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the stripattributes plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'Stripattributes'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+desc 'Publishes rdoc to rubyforge server'
+task :publish_rdoc => :rdoc do
+ cmd = "scp -r rdoc/* rmm5t@rubyforge.org:/var/www/gforge-projects/stripattributes"
+ puts "\nPublishing rdoc: #{cmd}\n\n"
+ system(cmd)
+end
+
diff --git a/lib/strip_attributes/strip_attributes.rb b/lib/strip_attributes/strip_attributes.rb
new file mode 100644
index 000000000..130d10185
--- /dev/null
+++ b/lib/strip_attributes/strip_attributes.rb
@@ -0,0 +1,37 @@
+module StripAttributes
+ # Strips whitespace from model fields and leaves nil values as nil.
+ # XXX this differs from official StripAttributes, as it doesn't make blank cells null.
+ def strip_attributes!(options = nil)
+ before_validation do |record|
+ attribute_names = StripAttributes.narrow(record.attribute_names, options)
+
+ attribute_names.each do |attribute_name|
+ value = record[attribute_name]
+ if value.respond_to?(:strip)
+ stripped = value.strip
+ if stripped != value
+ record[attribute_name] = (value.nil?) ? nil : stripped
+ end
+ end
+ end
+ end
+ end
+
+ # Necessary because Rails has removed the narrowing of attributes using :only
+ # and :except on Base#attributes
+ def self.narrow(attribute_names, options)
+ if options.nil?
+ attribute_names
+ else
+ if except = options[:except]
+ except = Array(except).collect { |attribute| attribute.to_s }
+ attribute_names - except
+ elsif only = options[:only]
+ only = Array(only).collect { |attribute| attribute.to_s }
+ attribute_names & only
+ else
+ raise ArgumentError, "Options does not specify :except or :only (#{options.keys.inspect})"
+ end
+ end
+ end
+end
diff --git a/lib/strip_attributes/test/strip_attributes_test.rb b/lib/strip_attributes/test/strip_attributes_test.rb
new file mode 100644
index 000000000..8158dc664
--- /dev/null
+++ b/lib/strip_attributes/test/strip_attributes_test.rb
@@ -0,0 +1,90 @@
+require "#{File.dirname(__FILE__)}/test_helper"
+
+module MockAttributes
+ def self.included(base)
+ base.column :foo, :string
+ base.column :bar, :string
+ base.column :biz, :string
+ base.column :baz, :string
+ end
+end
+
+class StripAllMockRecord < ActiveRecord::Base
+ include MockAttributes
+ strip_attributes!
+end
+
+class StripOnlyOneMockRecord < ActiveRecord::Base
+ include MockAttributes
+ strip_attributes! :only => :foo
+end
+
+class StripOnlyThreeMockRecord < ActiveRecord::Base
+ include MockAttributes
+ strip_attributes! :only => [:foo, :bar, :biz]
+end
+
+class StripExceptOneMockRecord < ActiveRecord::Base
+ include MockAttributes
+ strip_attributes! :except => :foo
+end
+
+class StripExceptThreeMockRecord < ActiveRecord::Base
+ include MockAttributes
+ strip_attributes! :except => [:foo, :bar, :biz]
+end
+
+class StripAttributesTest < Test::Unit::TestCase
+ def setup
+ @init_params = { :foo => "\tfoo", :bar => "bar \t ", :biz => "\tbiz ", :baz => "" }
+ end
+
+ def test_should_exist
+ assert Object.const_defined?(:StripAttributes)
+ end
+
+ def test_should_strip_all_fields
+ record = StripAllMockRecord.new(@init_params)
+ record.valid?
+ assert_equal "foo", record.foo
+ assert_equal "bar", record.bar
+ assert_equal "biz", record.biz
+ assert_equal "", record.baz
+ end
+
+ def test_should_strip_only_one_field
+ record = StripOnlyOneMockRecord.new(@init_params)
+ record.valid?
+ assert_equal "foo", record.foo
+ assert_equal "bar \t ", record.bar
+ assert_equal "\tbiz ", record.biz
+ assert_equal "", record.baz
+ end
+
+ def test_should_strip_only_three_fields
+ record = StripOnlyThreeMockRecord.new(@init_params)
+ record.valid?
+ assert_equal "foo", record.foo
+ assert_equal "bar", record.bar
+ assert_equal "biz", record.biz
+ assert_equal "", record.baz
+ end
+
+ def test_should_strip_all_except_one_field
+ record = StripExceptOneMockRecord.new(@init_params)
+ record.valid?
+ assert_equal "\tfoo", record.foo
+ assert_equal "bar", record.bar
+ assert_equal "biz", record.biz
+ assert_equal "", record.baz
+ end
+
+ def test_should_strip_all_except_three_fields
+ record = StripExceptThreeMockRecord.new(@init_params)
+ record.valid?
+ assert_equal "\tfoo", record.foo
+ assert_equal "bar \t ", record.bar
+ assert_equal "\tbiz ", record.biz
+ assert_equal "", record.baz
+ end
+end
diff --git a/lib/strip_attributes/test/test_helper.rb b/lib/strip_attributes/test/test_helper.rb
new file mode 100644
index 000000000..7d06c40db
--- /dev/null
+++ b/lib/strip_attributes/test/test_helper.rb
@@ -0,0 +1,20 @@
+require 'test/unit'
+require 'rubygems'
+require 'active_record'
+
+PLUGIN_ROOT = File.expand_path(File.join(File.dirname(__FILE__), ".."))
+
+$LOAD_PATH.unshift "#{PLUGIN_ROOT}/lib"
+require "#{PLUGIN_ROOT}/init"
+
+class ActiveRecord::Base
+ alias_method :save, :valid?
+ def self.columns()
+ @columns ||= []
+ end
+
+ def self.column(name, sql_type = nil, default = nil, null = true)
+ @columns ||= []
+ @columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type, null)
+ end
+end