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 +52 -0
- data/Rakefile +10 -0
- data/lib/activerecord-define_nils/model.rb +76 -0
- data/lib/activerecord-define_nils/railtie.rb +11 -0
- data/lib/activerecord-define_nils/version.rb +3 -0
- data/lib/activerecord-define_nils.rb +3 -0
- metadata +69 -0
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,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
|
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: []
|