attribution 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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