attribute_mapper 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.kick +6 -0
- data/HISTORY.rdoc +8 -0
- data/LICENSE +1 -1
- data/VERSION.yml +2 -2
- data/attribute_mapper.gemspec +7 -29
- data/lib/attribute_mapper.rb +89 -57
- data/test/attribute_mapper_test.rb +27 -0
- data/test/test_helper.rb +1 -0
- metadata +4 -2
data/.kick
ADDED
data/HISTORY.rdoc
ADDED
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2007-
|
1
|
+
Copyright (c) 2007-2010 Marcel Molina, Jr., Bruce Williams, Adam Keys
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
4
|
this software and associated documentation files (the "Software"), to deal in
|
data/VERSION.yml
CHANGED
data/attribute_mapper.gemspec
CHANGED
@@ -1,46 +1,25 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
5
2
|
|
6
3
|
Gem::Specification.new do |s|
|
7
4
|
s.name = %q{attribute_mapper}
|
8
|
-
s.version = "
|
5
|
+
s.version = "0.9.1"
|
9
6
|
|
10
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
8
|
s.authors = ["Marcel Molina Jr.", "Bruce Williams", "Adam Keys"]
|
12
|
-
s.date = %q{
|
9
|
+
s.date = %q{2009-03-10}
|
13
10
|
s.description = %q{Provides a transparent interface for mapping symbolic representations to a column in the database of a more primitive type.}
|
14
11
|
s.email = %q{adamkkeys@gmail.com}
|
15
|
-
s.
|
16
|
-
|
17
|
-
"README.md"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".gitignore",
|
21
|
-
"LICENSE",
|
22
|
-
"README.md",
|
23
|
-
"Rakefile",
|
24
|
-
"VERSION.yml",
|
25
|
-
"attribute_mapper.gemspec",
|
26
|
-
"init.rb",
|
27
|
-
"lib/attribute_mapper.rb",
|
28
|
-
"test/attribute_mapper_test.rb",
|
29
|
-
"test/test_helper.rb"
|
30
|
-
]
|
12
|
+
s.files = ["README.md", "VERSION.yml", "lib/attribute_mapper.rb", "test/attribute_mapper_test.rb"]
|
13
|
+
s.has_rdoc = true
|
31
14
|
s.homepage = %q{http://github.com/therealadam/attribute_mapper}
|
32
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
15
|
+
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
33
16
|
s.require_paths = ["lib"]
|
34
|
-
s.rubygems_version = %q{1.3.
|
17
|
+
s.rubygems_version = %q{1.3.1}
|
35
18
|
s.summary = %q{Map symbolic types to primitive types and stash them in a column.}
|
36
|
-
s.test_files = [
|
37
|
-
"test/attribute_mapper_test.rb",
|
38
|
-
"test/test_helper.rb"
|
39
|
-
]
|
40
19
|
|
41
20
|
if s.respond_to? :specification_version then
|
42
21
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
-
s.specification_version =
|
22
|
+
s.specification_version = 2
|
44
23
|
|
45
24
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
25
|
else
|
@@ -48,4 +27,3 @@ Gem::Specification.new do |s|
|
|
48
27
|
else
|
49
28
|
end
|
50
29
|
end
|
51
|
-
|
data/lib/attribute_mapper.rb
CHANGED
@@ -7,89 +7,121 @@ module AttributeMapper
|
|
7
7
|
|
8
8
|
module ClassMethods # @private
|
9
9
|
|
10
|
-
# Map a column in your table to a human-friendly attribute on your
|
11
|
-
#
|
12
|
-
# the attribute is updated, the value
|
13
|
-
# database.
|
10
|
+
# Map a column in your table to a human-friendly attribute on your
|
11
|
+
# model. When +attribute+ is accessed, it will return the key
|
12
|
+
# from the mapping hash. When the attribute is updated, the value
|
13
|
+
# from the mapping hash is written to the database.
|
14
14
|
#
|
15
15
|
# A class method is also added providing access to the mapping
|
16
|
-
# hash, i.e. defining an attribute
|
17
|
-
#
|
18
|
-
#
|
16
|
+
# hash, i.e. defining an attribute +status+ will add a
|
17
|
+
# +statuses+ class method that returns the hash passed to the
|
18
|
+
# +:to+ option.
|
19
19
|
#
|
20
|
-
# Predicates are also added to each object for each attribute. If
|
21
|
-
#
|
22
|
-
# returns true if the attribute value is
|
20
|
+
# Predicates are also added to each object for each attribute. If
|
21
|
+
# you have a key +open+ in your mapping, your objects will have
|
22
|
+
# an +open?+ method that returns true if the attribute value is
|
23
|
+
# +:open+
|
23
24
|
#
|
24
|
-
#
|
25
|
+
# Each attribute you map generates an options method, suitable for
|
26
|
+
# use in form helpers. If you define an attribute +status+,
|
27
|
+
# instances of your model will have a +status_options+ method
|
28
|
+
# that returns a sorted array of arrays containing
|
29
|
+
# humanized-option-name/value pairs. By default this array is
|
30
|
+
# sorted by the option name (closed/open/etc.) If you'd rather
|
31
|
+
# sort by value, pass +false+ to the options method. This method
|
32
|
+
# also will set the selected option for records where the
|
33
|
+
# attribute is already set.
|
34
|
+
#
|
35
|
+
# @example Define a Ticket model with a status column:
|
25
36
|
# map_attribute :status, :to => {:open => 1, :closed => 2}
|
26
37
|
#
|
27
38
|
# @param [String] attribute the column to map on
|
28
39
|
# @param [Hash] options the options for this attribute
|
29
|
-
# @option options [Hash] :to The enumeration to use for this
|
40
|
+
# @option options [Hash] :to The enumeration to use for this
|
41
|
+
# attribute. See example above.
|
30
42
|
def map_attribute(attribute, options)
|
31
43
|
mapping = options[:to]
|
32
44
|
verify_existence_of attribute
|
33
45
|
add_accessor_for attribute, mapping
|
34
46
|
add_predicates_for attribute, mapping.keys
|
35
47
|
override attribute
|
48
|
+
add_options_helper_for attribute, mapping
|
36
49
|
end
|
37
50
|
|
38
51
|
private
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
52
|
+
|
53
|
+
def add_accessor_for(attribute, mapping)
|
54
|
+
class_eval(<<-EVAL)
|
55
|
+
class << self
|
56
|
+
def #{attribute.to_s.pluralize}
|
57
|
+
#{mapping.inspect}
|
45
58
|
end
|
46
|
-
EVAL
|
47
59
|
end
|
60
|
+
EVAL
|
61
|
+
end
|
48
62
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
RUBY
|
63
|
+
def add_predicates_for(attribute, names)
|
64
|
+
names.each do |name|
|
65
|
+
class_eval(<<-RUBY)
|
66
|
+
def #{name}?
|
67
|
+
self.#{attribute} == :#{name}
|
56
68
|
end
|
69
|
+
RUBY
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_options_helper_for(attribute, mapping)
|
74
|
+
class_eval(<<-EVAL, __FILE__, __LINE__)
|
75
|
+
def #{attribute}_options(sort_by_keys=true)
|
76
|
+
options = self.class.#{attribute.to_s.pluralize}.sort { |l, r|
|
77
|
+
sort_by_keys ? l.first.to_s <=> r.first.to_s : l.last <=> r.last
|
78
|
+
}.map { |f|
|
79
|
+
[f[0].to_s.humanize, f[0]]
|
80
|
+
}
|
81
|
+
self.#{attribute}.present? ? [options, {:selected => self.#{attribute}}] : [options]
|
57
82
|
end
|
83
|
+
EVAL
|
84
|
+
end
|
85
|
+
|
86
|
+
def override(*args)
|
87
|
+
override_getters *args
|
88
|
+
override_setters *args
|
89
|
+
end
|
90
|
+
|
91
|
+
def override_getters(attribute)
|
92
|
+
class_eval(<<-EVAL)
|
93
|
+
def #{attribute}
|
94
|
+
self.class.#{attribute.to_s.pluralize}.invert[read_attribute(:#{attribute})]
|
95
|
+
end
|
96
|
+
EVAL
|
97
|
+
end
|
98
|
+
|
99
|
+
def override_setters(attribute)
|
100
|
+
class_eval(<<-EVAL)
|
101
|
+
def #{attribute}=(raw_value)
|
102
|
+
value = resolve_value_of :#{attribute}, raw_value
|
103
|
+
write_attribute(:#{attribute}, value)
|
104
|
+
end
|
105
|
+
EVAL
|
106
|
+
end
|
107
|
+
|
108
|
+
def verify_existence_of(attribute)
|
109
|
+
raise ArgumentError, "`#{attribute}' is not an attribute of `#{self}'" unless column_names.include?(attribute.to_s)
|
110
|
+
end
|
58
111
|
|
59
|
-
def override(*args)
|
60
|
-
override_getters *args
|
61
|
-
override_setters *args
|
62
|
-
end
|
63
|
-
|
64
|
-
def override_getters(attribute)
|
65
|
-
class_eval(<<-EVAL)
|
66
|
-
def #{attribute}
|
67
|
-
self.class.#{attribute.to_s.pluralize}.invert[read_attribute(:#{attribute})]
|
68
|
-
end
|
69
|
-
EVAL
|
70
|
-
end
|
71
|
-
|
72
|
-
def override_setters(attribute)
|
73
|
-
class_eval(<<-EVAL)
|
74
|
-
def #{attribute}=(raw_value)
|
75
|
-
value = resolve_value_of :#{attribute}, raw_value
|
76
|
-
write_attribute(:#{attribute}, value)
|
77
|
-
end
|
78
|
-
EVAL
|
79
|
-
end
|
80
|
-
|
81
|
-
def verify_existence_of(attribute)
|
82
|
-
raise ArgumentError, "`#{attribute}' is not an attribute of `#{self}'" unless column_names.include?(attribute.to_s)
|
83
|
-
end
|
84
112
|
end
|
85
113
|
|
86
114
|
module InstanceMethods
|
115
|
+
|
87
116
|
private
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
117
|
+
|
118
|
+
def resolve_value_of(attribute, raw_value)
|
119
|
+
check_value = raw_value.is_a?(String) ? raw_value.to_sym : raw_value
|
120
|
+
mapping = self.class.send(attribute.to_s.pluralize)
|
121
|
+
raise ArgumentError, "`#{check_value}' not present in attribute mapping `#{mapping.inspect}'" unless mapping.to_a.flatten.include? check_value
|
122
|
+
mapping[check_value] || check_value
|
123
|
+
end
|
124
|
+
|
94
125
|
end
|
126
|
+
|
95
127
|
end
|
@@ -68,7 +68,34 @@ class AttributeMapperTest < Test::Unit::TestCase
|
|
68
68
|
ticket.status = 500
|
69
69
|
end
|
70
70
|
end
|
71
|
+
|
72
|
+
should "work with mass assignment" do
|
73
|
+
ticket.update_attributes(:status => :open, :name => 'Red is too red')
|
74
|
+
end
|
75
|
+
|
76
|
+
should "work with attr_accessible" do
|
77
|
+
new_ticket = Class.new(ActiveRecord::Base) do
|
78
|
+
set_table_name "tickets"
|
71
79
|
|
80
|
+
include AttributeMapper
|
81
|
+
map_attribute :status, :to => {:open => 1, :closed => 2}
|
82
|
+
|
83
|
+
attr_accessible :status
|
84
|
+
end
|
85
|
+
|
86
|
+
t = new_ticket.new
|
87
|
+
t.status = :open
|
88
|
+
|
89
|
+
assert_equal :open, t.status
|
90
|
+
end
|
91
|
+
|
92
|
+
should "provide a helper for forms" do
|
93
|
+
assert_equal [[["Closed", :closed], ["Open", :open]]], ticket.status_options
|
94
|
+
assert_equal [[["Open", :open], ["Closed", :closed]]], ticket.status_options(false)
|
95
|
+
ticket.status = :open
|
96
|
+
assert_equal [[["Open", :open], ["Closed", :closed]], {:selected => :open}], ticket.status_options(false)
|
97
|
+
end
|
98
|
+
|
72
99
|
end
|
73
100
|
|
74
101
|
#######
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribute_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcel Molina Jr.
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2010-
|
14
|
+
date: 2010-02-23 00:00:00 -06:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
@@ -26,6 +26,8 @@ extra_rdoc_files:
|
|
26
26
|
- README.md
|
27
27
|
files:
|
28
28
|
- .gitignore
|
29
|
+
- .kick
|
30
|
+
- HISTORY.rdoc
|
29
31
|
- LICENSE
|
30
32
|
- README.md
|
31
33
|
- Rakefile
|