attribution 0.1.0 → 0.2.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.
data/README.md CHANGED
@@ -78,7 +78,7 @@ And then you can pass in a Hash or a String of JSON to initialize the object:
78
78
  }
79
79
  ]
80
80
  }}
81
-
81
+
82
82
  book = Book.new(json)
83
83
 
84
84
  The object is populated based on the data, the values are converted into the type defined by the attribute:
@@ -116,6 +116,33 @@ The reciprocating association is populated as well:
116
116
  >> book.chapters[2].book.title
117
117
  => "Rework"
118
118
 
119
+ You can access the values of all attributes as a hash:
120
+
121
+ >> pp book.attributes
122
+ {:id=>1,
123
+ :title=>"Rework",
124
+ :price=>#<BigDecimal:7f87db1f0b48,'0.22E2',9(18)>,
125
+ :published_on=>Tue, 09 Mar 2010,
126
+ :ebook_available=>true,
127
+ :used=>false,
128
+ :shipping_weight=>14.4,
129
+ :created_at=>2013-02-20 05:39:45 -0500,
130
+ :updated_at=>2013-02-20 05:40:37 -0500,
131
+ :time_zone=>(GMT-05:00) Eastern Time (US & Canada)}
132
+
133
+ You can also add any arbitrary metadata to any attribute:
134
+
135
+ class Book
136
+ include Attribution
137
+
138
+ decimal :price, :required => true, :doc => "Price in USD", :whatever => "why not?"
139
+ end
140
+
141
+ And retrieve that metadata any time:
142
+
143
+ >> Book.attributes
144
+ => [{:required=>true, :doc=>"Price in USD", :whatever=>"why not?", :name=>:price, :type=>:decimal}]
145
+
119
146
  ## Contributing
120
147
 
121
148
  1. Fork it
@@ -124,4 +151,4 @@ The reciprocating association is populated as well:
124
151
  4. Push to the branch (`git push origin my-new-feature`)
125
152
  5. Create new Pull Request
126
153
 
127
- [ar]: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
154
+ [ar]: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
data/attribution.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "attribution"
5
- gem.version = "0.1.0"
5
+ gem.version = "0.2.0"
6
6
  gem.authors = ["Paul Barry"]
7
7
  gem.email = ["mail@paulbarry.com"]
8
8
  gem.description = %q{Add attributes to Ruby objects}
data/lib/attribution.rb CHANGED
@@ -20,8 +20,9 @@ module Attribution
20
20
  end
21
21
  end
22
22
 
23
- def attributes
24
- self.class.attributes.inject({}) do |attrs, attr|
23
+ # TODO: Use associations argument as a way to specify which associations should be included
24
+ def attributes(*associations)
25
+ self.class.attribute_names.inject({}) do |attrs, attr|
25
26
  attrs[attr] = send(attr)
26
27
  attrs
27
28
  end
@@ -40,18 +41,25 @@ module Attribution
40
41
  @attributes ||= []
41
42
  end
42
43
 
44
+ def attribute_names
45
+ @attribute_names ||= attributes.map{|a| a[:name] }
46
+ end
47
+
48
+ def add_attribute(name, type, metadata={})
49
+ attr_reader name
50
+ attributes << (metadata || {}).merge(:name => name.to_sym, :type => type.to_sym)
51
+ end
52
+
43
53
  # Attribute macros
44
- def string(attr)
45
- attributes << attr.to_sym
46
- attr_reader(attr)
54
+ def string(attr, metadata={})
55
+ add_attribute(attr, :string, metadata)
47
56
  define_method("#{attr}=") do |arg|
48
57
  instance_variable_set("@#{attr}", arg.to_s)
49
58
  end
50
59
  end
51
60
 
52
- def boolean(attr)
53
- attributes << attr.to_sym
54
- attr_reader(attr)
61
+ def boolean(attr, metadata={})
62
+ add_attribute(attr, :boolean, metadata)
55
63
  define_method("#{attr}=") do |arg|
56
64
  v = case arg
57
65
  when String then BOOLEAN_TRUE_STRINGS.include?(arg.downcase)
@@ -63,33 +71,29 @@ module Attribution
63
71
  alias_method "#{attr}?", attr
64
72
  end
65
73
 
66
- def integer(attr)
67
- attributes << attr.to_sym
68
- attr_reader(attr)
74
+ def integer(attr, metadata={})
75
+ add_attribute(attr, :integer, metadata)
69
76
  define_method("#{attr}=") do |arg|
70
77
  instance_variable_set("@#{attr}", arg.to_i)
71
78
  end
72
79
  end
73
80
 
74
- def float(attr)
75
- attributes << attr.to_sym
76
- attr_reader(attr)
81
+ def float(attr, metadata={})
82
+ add_attribute(attr, :float, metadata)
77
83
  define_method("#{attr}=") do |arg|
78
84
  instance_variable_set("@#{attr}", arg.to_f)
79
85
  end
80
86
  end
81
87
 
82
- def decimal(attr)
83
- attributes << attr.to_sym
84
- attr_reader(attr)
88
+ def decimal(attr, metadata={})
89
+ add_attribute(attr, :decimal, metadata)
85
90
  define_method("#{attr}=") do |arg|
86
91
  instance_variable_set("@#{attr}", BigDecimal.new(arg.to_s))
87
92
  end
88
93
  end
89
94
 
90
- def date(attr)
91
- attributes << attr.to_sym
92
- attr_reader(attr)
95
+ def date(attr, metadata={})
96
+ add_attribute(attr, :date, metadata)
93
97
  define_method("#{attr}=") do |arg|
94
98
  v = case arg
95
99
  when Date then arg
@@ -101,10 +105,8 @@ module Attribution
101
105
  end
102
106
  end
103
107
 
104
- def time(attr)
105
- attributes << attr.to_sym
106
- attributes << attr.to_sym
107
- attr_reader(attr)
108
+ def time(attr, metadata={})
109
+ add_attribute(attr, :time, metadata)
108
110
  define_method("#{attr}=") do |arg|
109
111
  v = case arg
110
112
  when Date, DateTime then arg.to_time
@@ -116,20 +118,20 @@ module Attribution
116
118
  end
117
119
  end
118
120
 
119
- def time_zone(attr)
120
- attributes << attr.to_sym
121
- attr_reader(attr)
121
+ def time_zone(attr, metadata={})
122
+ add_attribute(attr, :time_zone, metadata)
122
123
  define_method("#{attr}=") do |arg|
123
124
  instance_variable_set("@#{attr}", ActiveSupport::TimeZone[arg.to_s])
124
125
  end
125
126
  end
126
127
 
127
128
  # Association macros
128
- def belongs_to(association_name)
129
+ def belongs_to(association_name, metadata={})
129
130
  # foo_id
130
- attributes << "#{association_name}_id".to_sym
131
- define_method("#{association_name}_id") do
132
- ivar = "@#{association_name}_id"
131
+ id_getter = "#{association_name}_id".to_sym
132
+ add_attribute(id_getter, :integer, metadata)
133
+ define_method(id_getter) do
134
+ ivar = "@#{id_getter}"
133
135
  if instance_variable_defined?(ivar)
134
136
  instance_variable_get(ivar)
135
137
  else
@@ -142,8 +144,8 @@ module Attribution
142
144
  end
143
145
 
144
146
  # foo_id=
145
- define_method("#{association_name}_id=") do |arg|
146
- instance_variable_set("@#{association_name}_id", arg.to_i)
147
+ define_method("#{id_getter}=") do |arg|
148
+ instance_variable_set("@#{id_getter}", arg.to_i)
147
149
  end
148
150
 
149
151
  # foo
@@ -1,3 +1,3 @@
1
1
  module Attribution
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,6 +1,17 @@
1
1
  require 'test/unit'
2
2
  require 'attribution'
3
3
 
4
+ #TODO: support using a different class name than the association name
5
+ class Author
6
+ include Attribution
7
+
8
+ integer :id
9
+ string :first_name
10
+ string :last_name
11
+
12
+ has_many :books
13
+ end
14
+
4
15
  class Book
5
16
  include Attribution
6
17
 
@@ -15,16 +26,28 @@ class Book
15
26
  time :updated_at
16
27
  time_zone :time_zone
17
28
 
29
+ belongs_to :book
18
30
  has_many :chapters
19
31
  end
20
32
 
21
33
  class Chapter
22
34
  include Attribution
23
35
 
24
- integer :number
36
+ integer :id
37
+ integer :number, :required => true, :doc => "Starts from 1"
25
38
  string :title
26
39
  integer :page_number
27
40
 
41
+ belongs_to :book
42
+ has_many :pages
43
+ end
44
+
45
+ class Page
46
+ include Attribution
47
+
48
+ integer :id
49
+ integer :page_number
50
+
28
51
  belongs_to :book
29
52
  end
30
53
 
@@ -82,7 +105,13 @@ class AttributionTest < Test::Unit::TestCase
82
105
 
83
106
  def test_attributes
84
107
  chapter = Chapter.new(:number => "1")
85
- assert_equal [:number, :title, :page_number, :book_id], Chapter.attributes
86
- assert_equal({ :number => 1, :title => nil, :page_number => nil, :book_id => nil }, chapter.attributes)
108
+ assert_equal [
109
+ { :name => :id, :type => :integer },
110
+ { :name => :number, :type => :integer, :required => true, :doc => "Starts from 1" },
111
+ { :name => :title, :type => :string },
112
+ { :name => :page_number, :type => :integer },
113
+ { :name => :book_id, :type => :integer }
114
+ ], Chapter.attributes
115
+ assert_equal({ :id => nil, :number => 1, :title => nil, :page_number => nil, :book_id => nil }, chapter.attributes)
87
116
  end
88
117
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-27 00:00:00.000000000 Z
12
+ date: 2013-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport