diff options
Diffstat (limited to 'lib/strip_attributes')
-rw-r--r-- | lib/strip_attributes/README.rdoc | 77 | ||||
-rw-r--r-- | lib/strip_attributes/Rakefile | 30 | ||||
-rw-r--r-- | lib/strip_attributes/strip_attributes.rb | 37 | ||||
-rw-r--r-- | lib/strip_attributes/test/strip_attributes_test.rb | 90 | ||||
-rw-r--r-- | lib/strip_attributes/test/test_helper.rb | 20 |
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 |