maskable_attribute 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/.gitignore +7 -0
- data/.rvmrc +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +37 -0
- data/MIT-LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +37 -0
- data/lib/maskable_attribute.rb +6 -0
- data/lib/maskable_attribute/acts_as_maskable_attribute.rb +48 -0
- data/lib/maskable_attribute/formatting.rb +71 -0
- data/lib/maskable_attribute/mask.rb +112 -0
- data/lib/maskable_attribute/maskable_attribute.rb +58 -0
- data/lib/maskable_attribute/version.rb +3 -0
- data/lib/tasks/maskable_attribute_tasks.rake +4 -0
- data/maskable_attribute.gemspec +22 -0
- data/test/dummy/Rakefile +10 -0
- data/test/dummy/app/controllers/application_controller.rb +10 -0
- data/test/dummy/app/helpers/application_helper.rb +3 -0
- data/test/dummy/app/models/hickwell.rb +6 -0
- data/test/dummy/config/boot.rb +128 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +41 -0
- data/test/dummy/config/environments/development.rb +17 -0
- data/test/dummy/config/environments/production.rb +28 -0
- data/test/dummy/config/environments/test.rb +28 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookie_verification_secret.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/new_rails_defaults.rb +21 -0
- data/test/dummy/config/initializers/session_store.rb +15 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/preinitializer.rb +20 -0
- data/test/dummy/config/routes.rb +43 -0
- data/test/dummy/db/migrate/20111220153853_create_hickwells.rb +15 -0
- data/test/dummy/db/schema.rb +23 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/public/404.html +30 -0
- data/test/dummy/public/422.html +30 -0
- data/test/dummy/public/500.html +30 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/images/rails.png +0 -0
- data/test/dummy/public/index.html +275 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +963 -0
- data/test/dummy/public/javascripts/dragdrop.js +973 -0
- data/test/dummy/public/javascripts/effects.js +1128 -0
- data/test/dummy/public/javascripts/prototype.js +4320 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/script/about +4 -0
- data/test/dummy/script/console +3 -0
- data/test/dummy/script/dbconsole +3 -0
- data/test/dummy/script/destroy +3 -0
- data/test/dummy/script/generate +3 -0
- data/test/dummy/script/performance/benchmarker +3 -0
- data/test/dummy/script/performance/profiler +3 -0
- data/test/dummy/script/plugin +3 -0
- data/test/dummy/script/runner +3 -0
- data/test/dummy/script/server +3 -0
- data/test/dummy/test/fixtures/hickwells.yml +9 -0
- data/test/dummy/test/test_helper.rb +40 -0
- data/test/dummy/test/unit/hickwell_test.rb +31 -0
- data/test/formatting_test.rb +71 -0
- data/test/mask_test.rb +95 -0
- data/test/maskable_attribute_test.rb +163 -0
- data/test/test_helper.rb +10 -0
- metadata +174 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use 1.9.2-p290@maskable_attribute
|
data/Gemfile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "rails", "~> 2.3.10"
|
|
4
|
+
gem "sqlite3"
|
|
5
|
+
|
|
6
|
+
# Declare your gem's dependencies in maskable_attribute.gemspec.
|
|
7
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
|
8
|
+
# development dependencies will be added by default to the :development group.
|
|
9
|
+
gemspec
|
|
10
|
+
|
|
11
|
+
# Declare any dependencies that are still in development here instead of in
|
|
12
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
|
13
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
14
|
+
# your gem to rubygems.org.
|
|
15
|
+
|
|
16
|
+
# To use debugger
|
|
17
|
+
# gem 'ruby-debug19', :require => 'ruby-debug'
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
maskable_attribute (0.0.1)
|
|
5
|
+
rails (>= 2.3.10)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: http://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
actionmailer (2.3.14)
|
|
11
|
+
actionpack (= 2.3.14)
|
|
12
|
+
actionpack (2.3.14)
|
|
13
|
+
activesupport (= 2.3.14)
|
|
14
|
+
rack (~> 1.1.0)
|
|
15
|
+
activerecord (2.3.14)
|
|
16
|
+
activesupport (= 2.3.14)
|
|
17
|
+
activeresource (2.3.14)
|
|
18
|
+
activesupport (= 2.3.14)
|
|
19
|
+
activesupport (2.3.14)
|
|
20
|
+
rack (1.1.3)
|
|
21
|
+
rails (2.3.14)
|
|
22
|
+
actionmailer (= 2.3.14)
|
|
23
|
+
actionpack (= 2.3.14)
|
|
24
|
+
activerecord (= 2.3.14)
|
|
25
|
+
activeresource (= 2.3.14)
|
|
26
|
+
activesupport (= 2.3.14)
|
|
27
|
+
rake (>= 0.8.3)
|
|
28
|
+
rake (0.9.2.2)
|
|
29
|
+
sqlite3 (1.3.6)
|
|
30
|
+
|
|
31
|
+
PLATFORMS
|
|
32
|
+
ruby
|
|
33
|
+
|
|
34
|
+
DEPENDENCIES
|
|
35
|
+
maskable_attribute!
|
|
36
|
+
rails (~> 2.3.10)
|
|
37
|
+
sqlite3
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2011 YOURNAME
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Maskable Attribute
|
|
2
|
+
|
|
3
|
+
maskable_attribute is an ActiveRecord extension that allows for 'masking' a records' attribute. It provides the ability to have an objects' attribute be dynamically assigned at a given point in time while providing the capability to make a one-location change that propagates through all resulting objects containing the resulting attribute mask.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
### Via rubygems:
|
|
8
|
+
|
|
9
|
+
gem install maskable_attribute
|
|
10
|
+
|
|
11
|
+
### Via bundler:
|
|
12
|
+
|
|
13
|
+
Add the following line to Gemfile:
|
|
14
|
+
|
|
15
|
+
gem 'maskable_attribute'
|
|
16
|
+
|
|
17
|
+
Then, run bundler:
|
|
18
|
+
|
|
19
|
+
bundle install
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
To use the maskable_attribute gem, simply create corresponding maskable_attribute attributes in the ActiveRecord model that you wish to affect.
|
|
24
|
+
|
|
25
|
+
For example, the following User class has a maskable attribute of :foo that can contain values of :bar, :baz and :qux
|
|
26
|
+
|
|
27
|
+
class User < ActiveRecord::Base
|
|
28
|
+
maskable_attribute :foo, [ :bar, :baz ]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Creating a user with the above mask can be performed via the following:
|
|
32
|
+
|
|
33
|
+
user = User.new :bar => "a", :baz => "b", :foo => "{bar}-{baz}"
|
|
34
|
+
|
|
35
|
+
Now that the user object is created, there are several accessor methods to return different variations of the attribute:
|
|
36
|
+
|
|
37
|
+
user.masks # { :foo => { :bar, :baz } }
|
|
38
|
+
user.foo.masks # [ :bar, :baz ]
|
|
39
|
+
user.foo # "a-b"
|
|
40
|
+
user.foo.unmasked # "{bar}-{baz}"
|
|
41
|
+
|
|
42
|
+
## Supported Ruby versions
|
|
43
|
+
|
|
44
|
+
Maskable Attribute supports Ruby 1.9.x+
|
|
45
|
+
|
|
46
|
+
## Additional Information
|
|
47
|
+
|
|
48
|
+
* [Git](https://github.com/billy-ran-away/maskable_attribute)
|
|
49
|
+
|
|
50
|
+
## Contributing
|
|
51
|
+
|
|
52
|
+
Contributions to the code-base are welcomed and handled via the normal Github pull request process.
|
|
53
|
+
|
|
54
|
+
## Owner
|
|
55
|
+
|
|
56
|
+
maskable_attribute is written and maintained by Bill Transue
|
data/Rakefile
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'MaskableAttribute'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Bundler::GemHelper.install_tasks
|
|
26
|
+
|
|
27
|
+
require 'rake/testtask'
|
|
28
|
+
|
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
|
30
|
+
t.libs << 'lib'
|
|
31
|
+
t.libs << 'test'
|
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
|
33
|
+
t.verbose = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
task :default => :test
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module MaskableAttribute
|
|
2
|
+
module ActsAsMaskableAttribute
|
|
3
|
+
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.send :extend, ClassMethods
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
##
|
|
10
|
+
# Specifies an attribute to be masked, followed by masks to be made available to the attribute.
|
|
11
|
+
#
|
|
12
|
+
# ==== Examples
|
|
13
|
+
#
|
|
14
|
+
# class Foo < ActiveRecord::Base
|
|
15
|
+
# maskable_attrribute :some_attribute, [ :some_method_be_used_as_a_mask, :another_attribute_mask ]
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
def maskable_attribute(attribute_to_mask, masks)
|
|
19
|
+
raise ArgumentError, "invalid argument (expected attribute)" unless column_names.include? attribute_to_mask.to_s
|
|
20
|
+
|
|
21
|
+
cattr_accessor :masks
|
|
22
|
+
self.masks ||= {}
|
|
23
|
+
self.masks[attribute_to_mask] = masks
|
|
24
|
+
self.masks
|
|
25
|
+
|
|
26
|
+
define_method attribute_to_mask do
|
|
27
|
+
send("maskable_#{attribute_to_mask}").to_s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
define_method "#{attribute_to_mask}=" do |value|
|
|
31
|
+
write_attribute attribute_to_mask, masked_attribute(attribute_to_mask).set(value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
define_method "maskable_#{attribute_to_mask}" do
|
|
35
|
+
masked_attribute attribute_to_mask
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
attr_accessor :masked_attribute
|
|
41
|
+
|
|
42
|
+
def masked_attribute(attribute)
|
|
43
|
+
@masked_attribute ||= MaskableAttribute.new self, attribute, self.class.masks[attribute]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
ActiveRecord::Base.send :include, MaskableAttribute::ActsAsMaskableAttribute
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module MaskableAttribute
|
|
2
|
+
module Formatting
|
|
3
|
+
class Formats < Hash
|
|
4
|
+
|
|
5
|
+
#{ :format => :two_digit }
|
|
6
|
+
#{ :formats => [ :upcase, :downcase ] }
|
|
7
|
+
#{ :exclusive_format => { :capitalized => Proc.new{ |mask| mask.captialized } } }
|
|
8
|
+
#{ :exclusive_formats =>{ :capitalized => Proc.new{ |mask| mask.captialized }, :titleized => :titleize } }
|
|
9
|
+
#{ :default_format => :titleize }
|
|
10
|
+
attr_accessor :are_exclusive, :has_default, :default
|
|
11
|
+
def initialize(options = {})
|
|
12
|
+
@are_exclusive, @has_default = false, false
|
|
13
|
+
@default = nil
|
|
14
|
+
unless options.nil?
|
|
15
|
+
options.each do |type, formats|
|
|
16
|
+
if formats.is_a? Symbol or formats.is_a? Proc
|
|
17
|
+
self[formats] = Format.new formats
|
|
18
|
+
elsif formats.is_a? Array
|
|
19
|
+
formats.each do |format|
|
|
20
|
+
self[format] = Format.new format
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
formats.each do |format, method|
|
|
24
|
+
self[format] = Format.new method || format
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if type.to_s.include? "exclusive"
|
|
29
|
+
@are_exclusive = true
|
|
30
|
+
elsif type.to_s.include? "default"
|
|
31
|
+
@has_default = true
|
|
32
|
+
@default = self[formats]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def apply(format, &block)
|
|
39
|
+
fetch(format, (has_default? ? @default : Format.new)).apply yield unless yield.nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def names
|
|
43
|
+
keys
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def are_exclusive?
|
|
47
|
+
@are_exclusive
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def has_default?
|
|
51
|
+
@has_default
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class Format
|
|
56
|
+
def initialize(method=nil)
|
|
57
|
+
@method = method
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def apply(input)
|
|
61
|
+
if @method.is_a? Symbol
|
|
62
|
+
input.send(@method)
|
|
63
|
+
elsif @method.is_a? Proc
|
|
64
|
+
@method.call input
|
|
65
|
+
else
|
|
66
|
+
input
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module MaskableAttribute
|
|
2
|
+
class Masks
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
#:bar
|
|
6
|
+
#:foo => :bar
|
|
7
|
+
#:foo => [ :bar, baz, :qux ]
|
|
8
|
+
#:foo => { :format => :two_digit }
|
|
9
|
+
#:foo => { :formats => [ :two_digit, :upcase, :downcase ] }
|
|
10
|
+
#:bar => { :exclusive_format => { :capitalized => Proc.new{ |mask| mask.captialized } } }
|
|
11
|
+
#:bar => { :exclusive_formats => { :capitalized => Proc.new{ |mask| mask.captialized }, :titleized => :titleize } }
|
|
12
|
+
#:baz => { :default_format => :titleize }
|
|
13
|
+
#:bar => [ :quux, { :formats => ... } ]
|
|
14
|
+
#:bar => [ Proc.new { |object| object.size * 3 }, { :formats => ... } ]
|
|
15
|
+
def initialize(masks)
|
|
16
|
+
@masks = masks.map do |mask|
|
|
17
|
+
if mask.is_a? Array
|
|
18
|
+
Mask.new mask.first => mask.last
|
|
19
|
+
else
|
|
20
|
+
Mask.new mask
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def each(&block)
|
|
26
|
+
@masks.each(&block)
|
|
27
|
+
return self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def [](accessor)
|
|
31
|
+
(find_by_accessor(accessor) || Mask.new).accessor(accessor)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def find_by_accessor(accessor)
|
|
35
|
+
@masks.find do |mask|
|
|
36
|
+
mask.accessed_by? accessor
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def names
|
|
41
|
+
@masks.map(&:name).map(&:to_sym)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class Mask
|
|
46
|
+
attr_accessor :accessor, :name, :method, :formats
|
|
47
|
+
|
|
48
|
+
def initialize(options=nil)
|
|
49
|
+
if options.is_a? Symbol
|
|
50
|
+
@name = @method = options.to_sym
|
|
51
|
+
options = {}
|
|
52
|
+
elsif options.is_a? Hash
|
|
53
|
+
@name, options = options.flatten
|
|
54
|
+
if options.is_a? Symbol or options.is_a? Proc
|
|
55
|
+
@method = options
|
|
56
|
+
options = {}
|
|
57
|
+
else
|
|
58
|
+
if options.is_a? Array
|
|
59
|
+
@method = options.shift
|
|
60
|
+
options = options.extract_options!
|
|
61
|
+
else
|
|
62
|
+
@method = @name
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
@formats = Formatting::Formats.new options
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def name
|
|
70
|
+
@name.to_s.tr "_", " "
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def accessor(*accessed_with)
|
|
74
|
+
if accessed_with.empty?
|
|
75
|
+
@accessor || ""
|
|
76
|
+
else
|
|
77
|
+
@accessor = accessed_with.first
|
|
78
|
+
self
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def unmask(*args)
|
|
83
|
+
object = args.first
|
|
84
|
+
options = args.extract_options!
|
|
85
|
+
format = options[:formatted] || accessor.sub(@name.to_s, "").strip.to_sym
|
|
86
|
+
|
|
87
|
+
formats.apply format do
|
|
88
|
+
begin
|
|
89
|
+
if @method.is_a? Proc
|
|
90
|
+
@method.call object
|
|
91
|
+
elsif @method.is_a? Symbol
|
|
92
|
+
object.send(@method) if object.respond_to? @method
|
|
93
|
+
else
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
rescue NoMethodError
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def accessed_by
|
|
103
|
+
formats.names.map { |format| format.to_s + " " + name}.tap do |accessed_by|
|
|
104
|
+
accessed_by.push name unless formats.are_exclusive?
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def accessed_by?(possible_accessor)
|
|
109
|
+
accessed_by.include? possible_accessor.tr('_', ' ')
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module MaskableAttribute
|
|
2
|
+
class MaskableAttribute
|
|
3
|
+
attr_accessor :object, :attribute, :masks
|
|
4
|
+
|
|
5
|
+
def initialize(object, attribute, masks)
|
|
6
|
+
@object = object
|
|
7
|
+
@attribute = attribute
|
|
8
|
+
@masks = Masks.new masks
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def masks
|
|
12
|
+
@masks.names
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def masked
|
|
16
|
+
value = unmasked
|
|
17
|
+
if !value.blank? and value.match(/\{.*\}/)
|
|
18
|
+
value.scan(/(?<={)[^}]+(?=})/).each do |mask| #mask: two_digit model_series
|
|
19
|
+
value = value.sub "{#{mask}}", @masks[mask].unmask(@object).to_s unless @masks[mask].unmask(@object).nil?
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
value
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
alias :to_s :masked
|
|
26
|
+
|
|
27
|
+
def masked_object
|
|
28
|
+
@object
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def unmasked
|
|
32
|
+
@object.read_attribute attribute
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def set(value)
|
|
36
|
+
unless value.blank?
|
|
37
|
+
@masks.each do |mask|
|
|
38
|
+
mask.accessed_by.each do |mask_accessor|
|
|
39
|
+
value.sub! /#{mask.unmask(@object, :formatted => mask_accessor)}(?![^{]*})/, "{#{mask_accessor}}" unless mask.unmask(@object).blank?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
value
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class InvalidMask < RuntimeError
|
|
47
|
+
attr :mask, :obj
|
|
48
|
+
def initialize(mask, obj)
|
|
49
|
+
@mask = mask
|
|
50
|
+
@obj = obj
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_s
|
|
54
|
+
"Invalid mask '#{@mask}' for #{@obj.class.name}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|