clear_empty_attributes 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Manifest
2
+ pkg
data/README.markdown ADDED
@@ -0,0 +1,38 @@
1
+ Problem
2
+ =======
3
+ When AR objects are saved, empty fields are saved as '' instead of nil.
4
+
5
+ - Complicates queries for empty fields (`WHERE field IS NULL OR field = ''`)
6
+ - Makes the use of `unless field.blank?` necessary (opposed to only `if field`)
7
+ - Can lead to late-detected bugs because most of the time strings were `filled or ''` and suddenly they are `nil`
8
+ - Some validations do not support `:allow_blank=>true`
9
+ - Databases can handle `NULL` better & faster than empty strings (especially when using `LIKE`)
10
+
11
+
12
+ Solution
13
+ ========
14
+ Defines an AR `before_validation` that sets empty Strings to nil.
15
+
16
+
17
+ Install
18
+ =======
19
+ ` script/plugin install git://github.com/collectiveidea/clear_empty_attributes.git `
20
+ OR
21
+ ` sudo gem install clear_empty_attributes -s http://gemcutter.org `
22
+
23
+
24
+ Migration
25
+ =========
26
+ When you are switching to `clear_empty_attributes`, run this task
27
+ to remove any `''` strings/texts from your database.
28
+
29
+ rake db:clear_empty_attributes
30
+ (only works when checked out or installed as plugin)
31
+
32
+
33
+ Authors
34
+ =======
35
+ - [Brandon Keepers](http://opensoul.org)
36
+ - [Michael Grosser](http://pragmatig.wordpress.com)
37
+
38
+ Hereby placed under public domain, do what you want, just do not hold anybody accountable...
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ desc "Run all specs in spec directory"
2
+ task :default do |t|
3
+ options = "--colour --format progress --loadby --reverse"
4
+ files = FileList['spec/**/*_spec.rb']
5
+ system("spec #{options} #{files}")
6
+ end
7
+
8
+ begin
9
+ require 'jeweler'
10
+ project_name = 'clear_empty_attributes'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = project_name
13
+ gem.description = gem.summary = "Save empty strings as nil to avoid lots of problems"
14
+ gem.email = "brandon@opensoul.org"
15
+ gem.homepage = "http://github.com/grosser/#{project_name}"
16
+ gem.authors = ["Brandon Keepers"]
17
+ gem.add_dependency ['activerecord']
18
+ end
19
+
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
23
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,55 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{clear_empty_attributes}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Brandon Keepers"]
12
+ s.date = %q{2009-11-13}
13
+ s.description = %q{Save empty strings as nil to avoid lots of problems}
14
+ s.email = %q{brandon@opensoul.org}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.markdown",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "clear_empty_attributes.gemspec",
24
+ "init.rb",
25
+ "lib/clear_empty_attributes.rb",
26
+ "spec/clear_empty_attributes_spec.rb",
27
+ "spec/setup_test_model.rb",
28
+ "spec/spec_helper.rb",
29
+ "tasks/clear_empty_attributes.rake"
30
+ ]
31
+ s.homepage = %q{http://github.com/grosser/clear_empty_attributes}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.5}
35
+ s.summary = %q{Save empty strings as nil to avoid lots of problems}
36
+ s.test_files = [
37
+ "spec/spec_helper.rb",
38
+ "spec/clear_empty_attributes_spec.rb",
39
+ "spec/setup_test_model.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<activerecord>, [">= 0"])
50
+ end
51
+ else
52
+ s.add_dependency(%q<activerecord>, [">= 0"])
53
+ end
54
+ end
55
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'clear_empty_attributes'
@@ -0,0 +1,15 @@
1
+ require 'activerecord'
2
+
3
+ class ActiveRecord::Base
4
+
5
+ before_validation :clear_empty_attrs
6
+ before_save :clear_empty_attrs # needed to work correctly with update_attribute too
7
+
8
+ protected
9
+
10
+ def clear_empty_attrs
11
+ @attributes.each do |key,value|
12
+ self[key] = nil if value.is_a?(String) && value.blank?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,88 @@
1
+ require "spec/spec_helper"
2
+
3
+ describe :clear_empty_attributes do
4
+ before do
5
+ @user = User.new(:name=>'Michael')
6
+ @user.save!
7
+ end
8
+
9
+ describe :validations do
10
+ it "is not valid with a invalid string" do
11
+ @user.name = 'a'
12
+ @user.should_not be_valid
13
+ end
14
+
15
+ it "is valid with a allow_nil field set to empty string" do
16
+ @user.name = ''
17
+ @user.should be_valid
18
+ end
19
+ end
20
+
21
+ describe :update_attributes do
22
+ it "stores non-empty strings normally" do
23
+ @user.update_attributes(:name=>'Hans')
24
+ @user.reload.name.should == 'Hans'
25
+ end
26
+
27
+ it "stores strings as nil" do
28
+ @user.update_attributes(:name=>'')
29
+ @user.reload.name.should == nil
30
+ end
31
+
32
+ it "does not affect booleans" do
33
+ @user.update_attributes(:sexy=>false)
34
+ @user.reload.sexy.should == false
35
+ end
36
+ end
37
+
38
+ describe :attributes= do
39
+ it "stores non-empty strings normally" do
40
+ @user.attributes = {'name'=>'Hans'}
41
+ @user.save!
42
+ @user.reload.name.should == 'Hans'
43
+ end
44
+
45
+ it "stores strings as nil" do
46
+ @user.attributes = {:name=>''}
47
+ @user.save!
48
+ @user.reload.name.should == nil
49
+ end
50
+ end
51
+
52
+ describe :update_attribute do
53
+ it "stores non-empty strings normally" do
54
+ @user.update_attribute(:name,'Hans')
55
+ @user.reload.name.should == 'Hans'
56
+ end
57
+
58
+ it "stores strings as nil" do
59
+ @user.update_attribute(:name,'')
60
+ @user.reload.name.should == nil
61
+ end
62
+
63
+ it "does not affect booleans" do
64
+ @user.update_attribute(:sexy,false)
65
+ @user.reload.sexy.should == false
66
+ end
67
+ end
68
+
69
+ describe :write_attribute do
70
+ it "stores non-empty strings normally" do
71
+ @user.write_attribute(:name,'Hans')
72
+ @user.save!
73
+ @user.reload.name.should == 'Hans'
74
+ end
75
+
76
+ it "stores strings as nil" do
77
+ @user.write_attribute(:name,'')
78
+ @user.save!
79
+ @user.reload.name.should == nil
80
+ end
81
+
82
+ it "does not affect booleans" do
83
+ @user.write_attribute(:sexy,false)
84
+ @user.save!
85
+ @user.reload.sexy.should == false
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,22 @@
1
+ # connect
2
+ ActiveRecord::Base.configurations = {"test" => {
3
+ :adapter => "sqlite3",
4
+ :database => ":memory:",
5
+ }.with_indifferent_access}
6
+
7
+ ActiveRecord::Base.establish_connection(:test)
8
+
9
+ # create table
10
+ ActiveRecord::Schema.define(:version => 1) do
11
+ create_table :users do |t|
12
+ t.string :name
13
+ t.boolean :sexy
14
+ t.integer :age
15
+ t.timestamps
16
+ end
17
+ end
18
+
19
+ # create model
20
+ class User < ActiveRecord::Base
21
+ validates_length_of :name, :within=>2..20, :allow_nil=>true
22
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH << 'lib'
2
+
3
+ require "init"
4
+ require "spec/setup_test_model.rb"
@@ -0,0 +1,16 @@
1
+ namespace :db do
2
+ desc "Clear all blank strings in the database. Specify TABLES=table1,table2 to limit to specific tables."
3
+ task :clear_empty_attributes => :environment do
4
+ connection = ActiveRecord::Base.connection
5
+ tables = ENV['TABLES'] ? ENV['TABLES'].split(/,/) : connection.tables
6
+ tables.each do |table|
7
+ puts "#{table}:"
8
+ connection.columns(table).select(&:text?).each do |column|
9
+ name = column.name
10
+ puts " #{name}"
11
+ column_name = connection.quote_column_name(column.name)
12
+ connection.update("UPDATE #{connection.quote_table_name(table)} SET #{column_name} = NULL WHERE #{column_name} = ''")
13
+ end
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clear_empty_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Brandon Keepers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-13 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Save empty strings as nil to avoid lots of problems
26
+ email: brandon@opensoul.org
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.markdown
33
+ files:
34
+ - .gitignore
35
+ - README.markdown
36
+ - Rakefile
37
+ - VERSION
38
+ - clear_empty_attributes.gemspec
39
+ - init.rb
40
+ - lib/clear_empty_attributes.rb
41
+ - spec/clear_empty_attributes_spec.rb
42
+ - spec/setup_test_model.rb
43
+ - spec/spec_helper.rb
44
+ - tasks/clear_empty_attributes.rake
45
+ has_rdoc: true
46
+ homepage: http://github.com/grosser/clear_empty_attributes
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Save empty strings as nil to avoid lots of problems
73
+ test_files:
74
+ - spec/spec_helper.rb
75
+ - spec/clear_empty_attributes_spec.rb
76
+ - spec/setup_test_model.rb