attr_encrypted 3.0.0 → 3.1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.travis.yml +37 -1
- data/CHANGELOG.md +22 -0
- data/README.md +16 -5
- data/Rakefile +1 -0
- data/attr_encrypted.gemspec +6 -1
- data/certs/saghaulor.pem +15 -15
- data/checksum/attr_encrypted-3.0.0.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.0.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.1.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.1.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.2.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.2.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.3.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.3.gem.sha512 +1 -0
- data/lib/attr_encrypted/adapters/active_record.rb +35 -20
- data/lib/attr_encrypted/version.rb +1 -1
- data/lib/attr_encrypted.rb +121 -102
- data/test/active_record_test.rb +76 -49
- data/test/attr_encrypted_test.rb +83 -7
- data/test/compatibility_test.rb +19 -21
- data/test/legacy_active_record_test.rb +7 -9
- data/test/legacy_compatibility_test.rb +13 -15
- data/test/test_helper.rb +7 -0
- data.tar.gz.sig +0 -0
- metadata +40 -32
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f602391484e3437daae62ddb60596f0b4cbc83e0
|
|
4
|
+
data.tar.gz: 5e407d7e299a43380057a2f0fe816da3a6ad1fca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77b697d9e450d6baae65fb3ed339824b8bf730898296f172c2ae6b4e0bd7368add0da29c76596b9bbf71d298fccd038195f7ffb7d153ffaeaf2aabc7bfc60f9f
|
|
7
|
+
data.tar.gz: 211f1c52e7f0505d55eef59f06bb139f47fb1ae0158b39a643b5c7c5251865f13b871ab7b3194d44cd2fc6a128e86a5c6b9c8669bab6d2870a7914ed5dacb6c3
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/.travis.yml
CHANGED
|
@@ -4,8 +4,10 @@ cache: bundler
|
|
|
4
4
|
rvm:
|
|
5
5
|
- 2.0
|
|
6
6
|
- 2.1
|
|
7
|
-
- 2.2
|
|
7
|
+
- 2.2.2
|
|
8
8
|
- 2.3.0
|
|
9
|
+
- 2.4.0
|
|
10
|
+
- 2.5.0
|
|
9
11
|
- rbx
|
|
10
12
|
env:
|
|
11
13
|
- ACTIVERECORD=3.0.0
|
|
@@ -14,8 +16,42 @@ env:
|
|
|
14
16
|
- ACTIVERECORD=4.0.0
|
|
15
17
|
- ACTIVERECORD=4.1.0
|
|
16
18
|
- ACTIVERECORD=4.2.0
|
|
19
|
+
- ACTIVERECORD=5.0.0
|
|
20
|
+
- ACTIVERECORD=5.1.1
|
|
17
21
|
matrix:
|
|
18
22
|
exclude:
|
|
23
|
+
- rvm: 2.0
|
|
24
|
+
env: ACTIVERECORD=5.0.0
|
|
25
|
+
- rvm: 2.0
|
|
26
|
+
env: ACTIVERECORD=5.1.1
|
|
27
|
+
- rvm: 2.1
|
|
28
|
+
env: ACTIVERECORD=5.0.0
|
|
29
|
+
- rvm: 2.1
|
|
30
|
+
env: ACTIVERECORD=5.1.1
|
|
31
|
+
- rvm: 2.4.0
|
|
32
|
+
env: ACTIVERECORD=3.0.0
|
|
33
|
+
- rvm: 2.4.0
|
|
34
|
+
env: ACTIVERECORD=3.1.0
|
|
35
|
+
- rvm: 2.4.0
|
|
36
|
+
env: ACTIVERECORD=3.2.0
|
|
37
|
+
- rvm: 2.4.0
|
|
38
|
+
env: ACTIVERECORD=4.0.0
|
|
39
|
+
- rvm: 2.4.0
|
|
40
|
+
env: ACTIVERECORD=4.1.0
|
|
41
|
+
- rvm: 2.5.0
|
|
42
|
+
env: ACTIVERECORD=3.0.0
|
|
43
|
+
- rvm: 2.5.0
|
|
44
|
+
env: ACTIVERECORD=3.1.0
|
|
45
|
+
- rvm: 2.5.0
|
|
46
|
+
env: ACTIVERECORD=3.2.0
|
|
47
|
+
- rvm: 2.5.0
|
|
48
|
+
env: ACTIVERECORD=4.0.0
|
|
49
|
+
- rvm: 2.5.0
|
|
50
|
+
env: ACTIVERECORD=4.1.0
|
|
51
|
+
- rvm: rbx
|
|
52
|
+
env: ACTIVERECORD=5.0.0
|
|
53
|
+
- rvm: rbx
|
|
54
|
+
env: ACTIVERECORD=5.1.1
|
|
19
55
|
allow_failures:
|
|
20
56
|
- rvm: rbx
|
|
21
57
|
fast_finish: true
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# attr_encrypted #
|
|
2
2
|
|
|
3
|
+
## 3.1.0 ##
|
|
4
|
+
* Added: Abitilty to encrypt empty values. (@tamird)
|
|
5
|
+
* Added: MIT license
|
|
6
|
+
* Added: MRI 2.5.x support (@saghaulor)
|
|
7
|
+
* Fixed: No long generate IV and salt if value is empty, unless :allow_empty_value options is passed. (@saghaulor)
|
|
8
|
+
* Fixed: Only generate IV and salt when :if and :unless options evaluate such that encryption should be performed. (@saghaulor)
|
|
9
|
+
* Fixed: Private methods are correctly evaluated as options. (@saghaulor)
|
|
10
|
+
* Fixed: Mark virtual attributes for Rails 5.x compatibility (@grosser)
|
|
11
|
+
* Fixed: Only check empty on strings, allows for encrypting non-string type objects
|
|
12
|
+
* Fixed: Fixed how accessors for db columns are defined in the ActiveRecord adapter, preventing premature definition. (@nagachika)
|
|
13
|
+
|
|
14
|
+
## 3.0.3 ##
|
|
15
|
+
* Fixed: attr_was would decrypt the attribute upon every call. This is inefficient and introduces problems when the options change between decrypting an old value and encrypting a new value; for example, when rotating the encryption key. As such, the new approach caches the decrypted value of the old encrypted value such that the old options are no longer needed. (@johnny-lai) (@saghaulor)
|
|
16
|
+
|
|
17
|
+
## 3.0.2 ##
|
|
18
|
+
* Changed: Removed alias_method_chain for compatibility with Rails v5.x (@grosser)
|
|
19
|
+
* Changed: Updated Travis build matrix to include Rails 5. (@saghaulor) (@connorshea)
|
|
20
|
+
* Changed: Removed `.silence_stream` from tests as it has been removed from Rails 5. (@sblackstone)
|
|
21
|
+
|
|
22
|
+
## 3.0.1 ##
|
|
23
|
+
* Fixed: attr_was method no longer calls undefined methods. (@saghaulor)
|
|
24
|
+
|
|
3
25
|
## 3.0.0 ##
|
|
4
26
|
* Changed: Updated gemspec to use Encryptor v3.0.0. (@saghaulor)
|
|
5
27
|
* Changed: Updated README with instructions related to moving from v2.0.0 to v3.0.0. (@saghaulor)
|
data/README.md
CHANGED
|
@@ -72,7 +72,7 @@ The `attr_encrypted` class method is also aliased as `attr_encryptor` to conform
|
|
|
72
72
|
|
|
73
73
|
### attr_encrypted with database persistence
|
|
74
74
|
|
|
75
|
-
By default, `attr_encrypted` uses the `:per_attribute_iv` encryption mode. This mode requires a column to store your cipher text and a column to store your IV.
|
|
75
|
+
By default, `attr_encrypted` uses the `:per_attribute_iv` encryption mode. This mode requires a column to store your cipher text and a column to store your IV (initialization vector).
|
|
76
76
|
|
|
77
77
|
Create or modify the table that your model uses to add a column with the `encrypted_` prefix (which can be modified, see below), e.g. `encrypted_ssn` via a migration like the following:
|
|
78
78
|
|
|
@@ -145,6 +145,7 @@ The following are the default options used by `attr_encrypted`:
|
|
|
145
145
|
decrypt_method: 'decrypt',
|
|
146
146
|
mode: :per_attribute_iv,
|
|
147
147
|
algorithm: 'aes-256-gcm',
|
|
148
|
+
allow_empty_value: false
|
|
148
149
|
```
|
|
149
150
|
|
|
150
151
|
All of the aforementioned options are explained in depth below.
|
|
@@ -195,7 +196,7 @@ If you don't like the `encrypted_#{attribute}` naming convention then you can sp
|
|
|
195
196
|
end
|
|
196
197
|
```
|
|
197
198
|
|
|
198
|
-
This would generate the following
|
|
199
|
+
This would generate the following attribute: `secret_email_crypted`.
|
|
199
200
|
|
|
200
201
|
|
|
201
202
|
### The `:key` option
|
|
@@ -296,7 +297,7 @@ You're probably going to be storing your encrypted attributes somehow (e.g. file
|
|
|
296
297
|
end
|
|
297
298
|
```
|
|
298
299
|
|
|
299
|
-
The default encoding is `m` (base64). You can change this by setting `encode: 'some encoding'`. See [`
|
|
300
|
+
The default encoding is `m` (base64). You can change this by setting `encode: 'some encoding'`. See [`Array#pack`](http://ruby-doc.org/core-2.3.0/Array.html#method-i-pack) for more encoding options.
|
|
300
301
|
|
|
301
302
|
|
|
302
303
|
### The `:marshal`, `:dump_method`, and `:load_method` options
|
|
@@ -311,6 +312,16 @@ You may want to encrypt objects other than strings (e.g. hashes, arrays, etc). I
|
|
|
311
312
|
|
|
312
313
|
You may also optionally specify `:marshaler`, `:dump_method`, and `:load_method` if you want to use something other than the default `Marshal` object.
|
|
313
314
|
|
|
315
|
+
### The `:allow_empty_value` option
|
|
316
|
+
|
|
317
|
+
You may want to encrypt empty strings or nil so as to not reveal which records are populated and which records are not.
|
|
318
|
+
|
|
319
|
+
```ruby
|
|
320
|
+
class User
|
|
321
|
+
attr_encrypted :credentials, key: 'some secret key', marshal: true, allow_empty_value: true
|
|
322
|
+
end
|
|
323
|
+
```
|
|
324
|
+
|
|
314
325
|
|
|
315
326
|
## ORMs
|
|
316
327
|
|
|
@@ -400,10 +411,10 @@ It is recommended that you implement a strategy to insure that you do not mix th
|
|
|
400
411
|
|
|
401
412
|
```ruby
|
|
402
413
|
class User
|
|
403
|
-
attr_encrypted :ssn, key: :encryption_key, v2_gcm_iv:
|
|
414
|
+
attr_encrypted :ssn, key: :encryption_key, v2_gcm_iv: is_decrypting?(:ssn)
|
|
404
415
|
|
|
405
416
|
def is_decrypting?(attribute)
|
|
406
|
-
|
|
417
|
+
encrypted_attributes[attribute][:operation] == :decrypting
|
|
407
418
|
end
|
|
408
419
|
end
|
|
409
420
|
|
data/Rakefile
CHANGED
data/attr_encrypted.gemspec
CHANGED
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.authors = ['Sean Huber', 'S. Brent Faulkner', 'William Monk', 'Stephen Aghaulor']
|
|
18
18
|
s.email = ['seah@shuber.io', 'sbfaulkner@gmail.com', 'billy.monk@gmail.com', 'saghaulor@gmail.com']
|
|
19
19
|
s.homepage = 'http://github.com/attr-encrypted/attr_encrypted'
|
|
20
|
+
s.license = 'MIT'
|
|
20
21
|
|
|
21
22
|
s.has_rdoc = false
|
|
22
23
|
s.rdoc_options = ['--line-numbers', '--inline-source', '--main', 'README.rdoc']
|
|
@@ -41,6 +42,10 @@ Gem::Specification.new do |s|
|
|
|
41
42
|
s.add_development_dependency('rake')
|
|
42
43
|
s.add_development_dependency('minitest')
|
|
43
44
|
s.add_development_dependency('sequel')
|
|
45
|
+
if RUBY_VERSION < '2.1.0'
|
|
46
|
+
s.add_development_dependency('nokogiri', '< 1.7.0')
|
|
47
|
+
s.add_development_dependency('public_suffix', '< 3.0.0')
|
|
48
|
+
end
|
|
44
49
|
if defined?(RUBY_ENGINE) && RUBY_ENGINE.to_sym == :jruby
|
|
45
50
|
s.add_development_dependency('activerecord-jdbcsqlite3-adapter')
|
|
46
51
|
s.add_development_dependency('jdbc-sqlite3', '< 3.8.7') # 3.8.7 is nice and broke
|
|
@@ -50,7 +55,7 @@ Gem::Specification.new do |s|
|
|
|
50
55
|
s.add_development_dependency('dm-sqlite-adapter')
|
|
51
56
|
s.add_development_dependency('simplecov')
|
|
52
57
|
s.add_development_dependency('simplecov-rcov')
|
|
53
|
-
s.add_development_dependency("codeclimate-test-reporter")
|
|
58
|
+
s.add_development_dependency("codeclimate-test-reporter", '<= 0.6.0')
|
|
54
59
|
|
|
55
60
|
s.cert_chain = ['certs/saghaulor.pem']
|
|
56
61
|
s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
|
data/certs/saghaulor.pem
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
|
2
2
|
MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlzYWdo
|
|
3
3
|
YXVsb3IxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
|
4
|
-
|
|
4
|
+
bTAeFw0xODAyMTIwMzMzMThaFw0xOTAyMTIwMzMzMThaMEAxEjAQBgNVBAMMCXNh
|
|
5
5
|
Z2hhdWxvcjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOLqbSmj5txfw39a
|
|
7
|
+
Ki0g3BJWGrfGBiSRq9aThUGzoiaqyDo/m1WMQdgPioZG+P923okChEWFjhSymBQU
|
|
8
|
+
eMdys6JRPm5ortp5sh9gesOWoozqb8R55d8rr1V7pY533cCut53Kb1wiitjkfXjR
|
|
9
|
+
efT2HPh6nV6rYjGMJek/URaCNzsZo7HCkRsKdezP+BKr4V4wOka69tfJX5pcvFvR
|
|
10
|
+
iiqfaiP4RK12hYdsFnSVKiKP7SAFTFiYcohbL8TUW6ezQQqJCK0M6fu74EWVCnBS
|
|
11
|
+
gFVjj931BuD8qhuxMiB6uC6FKxemB5TRGBLzn7RcrOMAo2inMAopjkGeQJUAyVCm
|
|
12
|
+
J5US3wIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
|
|
13
|
+
hJEuSZgvuuIhIsxQ/0pRQTBVzokwHgYDVR0RBBcwFYETc2FnaGF1bG9yQGdtYWls
|
|
14
14
|
LmNvbTAeBgNVHRIEFzAVgRNzYWdoYXVsb3JAZ21haWwuY29tMA0GCSqGSIb3DQEB
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
BQUAA4IBAQCsBS2cxqTmV4nXJEH/QbdgjVDAZbK6xf2gpM3vCRlYsy7Wz6GEoOpD
|
|
16
|
+
bzRkjxZwGNbhXShMUZwm6zahYQ/L1/HFztLoMBMkm8EIfPxH0PDrP4aWl0oyWxmU
|
|
17
|
+
OLm0/t9icSWRPPJ1tLJvuAaDdVpY5dEHd6VdnNJGQC5vHKRInt1kEyqEttIJ/xmJ
|
|
18
|
+
leSEFyMeoFsR+C/WPG9WSC+xN0eXqakCu6YUJoQzCn/7znv8WxpHEbeZjNIHq0qb
|
|
19
|
+
nbqZ/ZW1bwzj1T/NIbnMr37wqV29XwkI4+LbewMkb6/bDPYl0qZpAkCxKtGYCCJp
|
|
20
|
+
l6KPs9K/72yH00dxuAhiTXikTkcLXeQJ
|
|
21
21
|
-----END CERTIFICATE-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
845fc3cb09a19c3ac76192aba443788f92c880744617bca99b16fd31ce843e07
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
81a065442258cc3702aab62c7b2307a48ed3e0deb803600d11a7480cce0db7c43fd9929acd2755081042f8989236553fd694b6cb62776bbfc53f9165a22cbca1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
33140af4b223177db7a19efb2fa38472a299a745b29ca1c5ba9d3fa947390b77
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0c467cab98b9b2eb331f9818323a90ae01392d6cb03cf1f32faccc954d0fc54be65f0fc7bf751b0fce57925eef1c9e2af90181bc40d81ad93e21d15a001c53c6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c1256b459336d4a2012a0d0c70ce5cd3dac46acb5e78da6f77f6f104cb1e8b7b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dca0c8a729974c0e26fde4cd4216c7d0f66d9eca9f6cf0ccca64999f5180a00bf7c05b630c1d420ec1673141a2923946e8bd28b12e711faf64a4cd42c7a3ac9e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6d84c64852c4bbc0926b92fe7a93295671a9e69cb2939b96fb1e4b5e8a5b33b6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0f960e8a2f63c747c273241f7395dcceb0dd8a6f79349bee453db741fc7ea5ceb4342d7d5908e540e3b5acea2216ff38bef8c743e6e7c8559bacb4a731ab27c4
|
|
@@ -6,19 +6,20 @@ if defined?(ActiveRecord::Base)
|
|
|
6
6
|
base.class_eval do
|
|
7
7
|
|
|
8
8
|
# https://github.com/attr-encrypted/attr_encrypted/issues/68
|
|
9
|
-
|
|
9
|
+
alias_method :reload_without_attr_encrypted, :reload
|
|
10
|
+
def reload(*args, &block)
|
|
10
11
|
result = reload_without_attr_encrypted(*args, &block)
|
|
11
12
|
self.class.encrypted_attributes.keys.each do |attribute_name|
|
|
12
13
|
instance_variable_set("@#{attribute_name}", nil)
|
|
13
14
|
end
|
|
14
15
|
result
|
|
15
16
|
end
|
|
16
|
-
alias_method_chain :reload, :attr_encrypted
|
|
17
17
|
|
|
18
18
|
attr_encrypted_options[:encode] = true
|
|
19
19
|
|
|
20
20
|
class << self
|
|
21
|
-
|
|
21
|
+
alias_method :method_missing_without_attr_encrypted, :method_missing
|
|
22
|
+
alias_method :method_missing, :method_missing_with_attr_encrypted
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def perform_attribute_assignment(method, new_attributes, *args)
|
|
@@ -30,16 +31,16 @@ if defined?(ActiveRecord::Base)
|
|
|
30
31
|
private :perform_attribute_assignment
|
|
31
32
|
|
|
32
33
|
if ::ActiveRecord::VERSION::STRING > "3.1"
|
|
33
|
-
|
|
34
|
+
alias_method :assign_attributes_without_attr_encrypted, :assign_attributes
|
|
35
|
+
def assign_attributes(*args)
|
|
34
36
|
perform_attribute_assignment :assign_attributes_without_attr_encrypted, *args
|
|
35
37
|
end
|
|
36
|
-
alias_method_chain :assign_attributes, :attr_encrypted
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
alias_method :attributes_without_attr_encrypted=, :attributes=
|
|
41
|
+
def attributes=(*args)
|
|
40
42
|
perform_attribute_assignment :attributes_without_attr_encrypted=, *args
|
|
41
43
|
end
|
|
42
|
-
alias_method_chain :attributes=, :attr_encrypted
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
|
|
@@ -50,22 +51,35 @@ if defined?(ActiveRecord::Base)
|
|
|
50
51
|
super
|
|
51
52
|
options = attrs.extract_options!
|
|
52
53
|
attr = attrs.pop
|
|
54
|
+
attribute attr if ::ActiveRecord::VERSION::STRING >= "5.1.0"
|
|
53
55
|
options.merge! encrypted_attributes[attr]
|
|
54
56
|
|
|
55
|
-
define_method("#{attr}
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
define_method("#{attr}_was") do
|
|
58
|
+
attribute_was(attr)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if ::ActiveRecord::VERSION::STRING >= "4.1"
|
|
62
|
+
define_method("#{attr}_changed?") do |options = {}|
|
|
63
|
+
attribute_changed?(attr, options)
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
define_method("#{attr}_changed?") do
|
|
67
|
+
attribute_changed?(attr)
|
|
58
68
|
end
|
|
59
69
|
end
|
|
60
70
|
|
|
61
|
-
define_method("#{attr}
|
|
62
|
-
|
|
63
|
-
encrypted_attributes[attr].merge!(iv_and_salt)
|
|
64
|
-
evaluated_options = evaluated_attr_encrypted_options_for(attr)
|
|
65
|
-
[:iv, :salt, :operation].each { |key| encrypted_attributes[attr].delete(key) }
|
|
66
|
-
self.class.decrypt(attr, send("#{options[:attribute]}_was"), evaluated_options)
|
|
71
|
+
define_method("#{attr}_change") do
|
|
72
|
+
attribute_change(attr)
|
|
67
73
|
end
|
|
68
74
|
|
|
75
|
+
define_method("#{attr}_with_dirtiness=") do |value|
|
|
76
|
+
attribute_will_change!(attr) if value != __send__(attr)
|
|
77
|
+
__send__("#{attr}_without_dirtiness=", value)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
alias_method "#{attr}_without_dirtiness=", "#{attr}="
|
|
81
|
+
alias_method "#{attr}=", "#{attr}_with_dirtiness="
|
|
82
|
+
|
|
69
83
|
alias_method "#{attr}_before_type_cast", attr
|
|
70
84
|
end
|
|
71
85
|
|
|
@@ -74,16 +88,17 @@ if defined?(ActiveRecord::Base)
|
|
|
74
88
|
# methods returned to let ActiveRecord define the accessor methods
|
|
75
89
|
# for the db columns
|
|
76
90
|
|
|
77
|
-
|
|
78
|
-
connected = ::ActiveRecord::Base.connection_pool.with_connection(&:active?) rescue false
|
|
79
|
-
|
|
80
|
-
if connected && table_exists?
|
|
91
|
+
if connected? && table_exists?
|
|
81
92
|
columns_hash.keys.inject(super) {|instance_methods, column_name| instance_methods.concat [column_name.to_sym, :"#{column_name}="]}
|
|
82
93
|
else
|
|
83
94
|
super
|
|
84
95
|
end
|
|
85
96
|
end
|
|
86
97
|
|
|
98
|
+
def attribute_instance_methods_as_symbols_available?
|
|
99
|
+
connected? && table_exists?
|
|
100
|
+
end
|
|
101
|
+
|
|
87
102
|
# Allows you to use dynamic methods like <tt>find_by_email</tt> or <tt>scoped_by_email</tt> for
|
|
88
103
|
# encrypted attributes
|
|
89
104
|
#
|