activerecord-define_nils 0.0.1

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/README.md ADDED
@@ -0,0 +1,52 @@
1
+ Define Nils for ActiveRecord 3.x/4.x and Rails 3.x/4.x
2
+ =====
3
+
4
+ If working with a legacy database used by another application that uses a non-null value to mean null, you may need to translate certain values to nil to make them more normal to work with in Ruby/Rails and then save nil as a specific value.
5
+
6
+ For example, if nil is stored as 0 in `my_id`:
7
+
8
+ define_nils as: 0, for: :my_id
9
+
10
+ If nil is stored as 0 in `my_id` and `your_id`:
11
+
12
+ define_nils as: 0, for: [:my_id, :your_id]
13
+
14
+ If you want to accept 0 or '' as nil for `my_id` but save nil as 0:
15
+
16
+ define_nils as: [0, ''], for: :my_id, saving_as: 0
17
+
18
+ It will choose the only/first element in the as if you don't specify `saving_as`, so a less clear way to define that is:
19
+
20
+ define_nils as: [0, ''], for: :my_id
21
+
22
+ If you want to accept 0 or '' as nil for `my_id` and `your_id` but save nil as nil/null:
23
+
24
+ define_nils as: [0, ''], for: [:my_id, :your_id], saving_as: nil
25
+
26
+ It handles `read_attribute` calls, calls to the attribute name, and all `belongs_to` associations defined after the `define_nils` that use the specified attribute as a foreign_key. It also will show the value as nil in calls to inspect/returned values in rails console. So, for the most part it should look as if the value is nil within Ruby but on the database-side, nil is stored as whatever value you want to represent nil.
27
+
28
+ ### Setup
29
+
30
+ In your ActiveRecord/Rails 3.1+ project, add this to your Gemfile:
31
+
32
+ gem 'activerecord-define_nils'
33
+
34
+ For the development version:
35
+
36
+ gem 'activerecord-define_nils', :git => 'git://github.com/garysweaver/activerecord-define_nils.git'
37
+
38
+ Then run:
39
+
40
+ bundle install
41
+
42
+ ### Usage
43
+
44
+ If you are on Rails, the concern `ActiveRecordDefineNils::Model` is included automatically in `ActiveRecord::Base` via railtie.
45
+
46
+ Be sure to place `define_nils` above your `belongs_to` associations in the model class or those associations will query on unaltered foreign key values, which is probably not what you want.
47
+
48
+ ### License
49
+
50
+ Copyright (c) 2012 Gary S. Weaver, released under the [MIT license][lic].
51
+
52
+ [lic]: http://github.com/garysweaver/activerecord-define_nils/blob/master/LICENSE
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new(:test) do |t|
4
+ t.libs << 'test'
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ t.verbose = true
7
+ end
8
+
9
+ desc "Run tests"
10
+ task :default => :test
@@ -0,0 +1,76 @@
1
+ module ActiveRecordDefineNils
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :nil_definitions, instance_writer: false
7
+ class_attribute :nil_saved_as, instance_writer: false
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def define_nils(options)
13
+ raise ArgumentError.new("define_nils takes a hash, but got #{options.inspect}") unless options.is_a?(Hash)
14
+ if options.has_key?(:as) && options.has_key?(:for)
15
+ self.nil_saved_as ||= {}
16
+ self.nil_definitions ||= {}
17
+ as_vals = Array.wrap(options[:as])
18
+ raise ArgumentError.new("define_nils must supply at least one value for :as, but got #{options.inspect}") if as_vals.size == 0
19
+ Array.wrap(options[:for]).each do |attr_name|
20
+ attr_sym = attr_name.to_sym
21
+ self.nil_saved_as[attr_sym] = options[:saving_as] || as_vals[0]
22
+ self.nil_definitions[attr_sym] = as_vals
23
+ class_eval "def #{attr_name}; value = super(); self.nil_definitions && self.nil_definitions[#{attr_sym.inspect}] && self.nil_definitions[#{attr_sym.inspect}].include?(value) ? nil : value; end"
24
+ end
25
+ else
26
+ raise ArgumentError.new("define_nils must at least supply :as and :for, but got #{options.inspect}")
27
+ end
28
+ end
29
+
30
+ def belongs_to(*args)
31
+ super(*args)
32
+ return unless self.nil_definitions
33
+ # after belongs_to is finished, we wrap it
34
+ self.nil_definitions.keys.each do |attr_sym|
35
+ self.reflections.collect {|association_name, reflection|
36
+ if reflection.macro == :belongs_to && reflection.foreign_key.to_sym == attr_sym
37
+ class_eval "def #{association_name}; return nil if send(#{attr_sym.inspect}).nil?; super(); end"
38
+ end
39
+ }
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ def read_attribute(attr_name)
46
+ value = super(attr_name)
47
+ self.nil_definitions && self.nil_definitions[attr_name.to_sym] && self.nil_definitions[attr_name.to_sym].include?(value) ? nil : value
48
+ end
49
+
50
+ private
51
+
52
+ def create
53
+ if self.nil_saved_as
54
+ self.nil_saved_as.each do |column, translated_nil|
55
+ if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
56
+ write_attribute(column.to_s, translated_nil)
57
+ end
58
+ end
59
+ end
60
+
61
+ super
62
+ end
63
+
64
+ def update(*args)
65
+ if self.nil_saved_as
66
+ self.nil_saved_as.each do |column, translated_nil|
67
+ if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
68
+ write_attribute(column.to_s, translated_nil)
69
+ end
70
+ end
71
+ end
72
+
73
+ super
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,11 @@
1
+ require 'activerecord-define_nils'
2
+
3
+ module ActiveRecordDefineNils
4
+ class Railtie < Rails::Railtie
5
+ initializer "define_nils.active_record" do
6
+ ActiveSupport.on_load(:active_record) do
7
+ include ActiveRecordDefineNils::Model
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRecordDefineNils
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'activerecord-define_nils/version'
2
+ require 'activerecord-define_nils/model'
3
+ require 'activerecord-define_nils/railtie' if defined?(Rails)
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-define_nils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gary S. Weaver
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Allows you to redefine what is translated to nil on read and what is
31
+ stored instead of nil for specified attributes.
32
+ email:
33
+ - garysweaver@gmail.com
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - lib/activerecord-define_nils/model.rb
39
+ - lib/activerecord-define_nils/railtie.rb
40
+ - lib/activerecord-define_nils/version.rb
41
+ - lib/activerecord-define_nils.rb
42
+ - Rakefile
43
+ - README.md
44
+ homepage: https://github.com/garysweaver/activerecord-define_nils
45
+ licenses:
46
+ - MIT
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.24
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Define nils for ActiveRecord 3.x/4.x.
69
+ test_files: []