matic 0.1.1 → 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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ = 0.2.0
2
+
3
+ * Changed Matic.field to Matic.fields
4
+ * Added support for short field names
5
+
1
6
  = 0.1.0
2
7
 
3
8
  * Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- matic (0.1.1)
4
+ matic (0.2.0)
5
5
  activemodel (~> 3.0.0)
6
6
  activesupport (~> 3.0.0)
7
7
  mongomatic (~> 0.6.0)
data/README.md CHANGED
@@ -1,31 +1,54 @@
1
1
  # Matic
2
2
 
3
- Matic adds attribute accessors and dirty tracking to Mongomatic.
3
+ Matic adds attribute accessors and dirty tracking to Mongomatic and
4
+ optionally shortens field names to optimize storing and indexing.
4
5
 
5
6
  ## Examples
6
7
 
7
8
  class Person < Mongomatic::Base
8
9
  include Matic
9
10
 
10
- field :name
11
+ fields :first_name,
12
+ :last_name
11
13
  end
12
14
 
13
15
  person = Person.new
14
- person.name = "John Doe"
16
+ person.first_name = "John"
15
17
 
16
- person.name_changed?
18
+ person.first_name_changed?
17
19
  => true
18
20
 
19
- person.changes["name"]
20
- => [nil, "John Doe"]
21
+ person.changes["first_name"]
22
+ => [nil, "John"]
21
23
 
22
24
  person.insert
23
25
 
24
- person.name_changed?
26
+ person.first_name_changed?
25
27
  => false
26
28
 
27
- person.changes["name"]
29
+ person.changes["first_name"]
28
30
  => nil
29
31
 
30
- person.previous_changes["name"]
31
- => [nil, "John Doe"]
32
+ person.previous_changes["first_name"]
33
+ => [nil, "John"]
34
+
35
+ This is a model with short field names:
36
+
37
+ class Person < Mongomatic::Base
38
+ include Matic
39
+
40
+ fields :first_name => 'f',
41
+ :last_name => 'l'
42
+
43
+ end
44
+
45
+ person = Person.new
46
+
47
+ person.first_name = "John"
48
+ person.last_name = "Doe"
49
+
50
+ person.insert
51
+ => #<Person:0x000001023cea30
52
+ @doc=
53
+ {"f"=>"John", "l" => "Doe", "_id"=>BSON::ObjectId('4cdd1b0c6aa2b112e1000001')}
54
+ ...>
data/lib/matic.rb CHANGED
@@ -9,33 +9,31 @@ module Matic
9
9
  self.name.tableize
10
10
  end
11
11
 
12
- def field(attr_name)
13
- generate_attribute_methods(attr_name)
12
+ def fields(*attrs)
13
+ if attrs.first.is_a? Hash
14
+ attrs.first.each { |k, v| define_accessor(k, v) }
15
+ define_attribute_methods(attrs.first.keys)
16
+ else
17
+ attrs.each { |k, v| define_accessor(k, v) }
18
+ define_attribute_methods(attrs)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def define_accessor(attr_name, attr_field=nil)
25
+ attr_field ||= attr_name
14
26
 
15
27
  define_method(attr_name) do
16
- self[attr_name.to_s]
28
+ self[attr_field.to_s]
17
29
  end
18
30
 
19
31
  define_method("#{attr_name}=") do |val|
20
- unless val == self[attr_name.to_s]
32
+ unless val == self[attr_field.to_s]
21
33
  eval("#{attr_name}_will_change!")
22
34
  end
23
35
 
24
- self[attr_name.to_s] = val
25
- end
26
- end
27
-
28
- private
29
-
30
- def generate_attribute_methods(attr_name)
31
- attribute_method_matchers.each do |matcher|
32
- method_name = matcher.method_name(attr_name)
33
-
34
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
35
- def #{method_name}(*args)
36
- send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
37
- end
38
- STR
36
+ self[attr_field.to_s] = val
39
37
  end
40
38
  end
41
39
  end
@@ -44,18 +42,10 @@ module Matic
44
42
  clear_changes if super
45
43
  end
46
44
 
47
- def insert!(opts={})
48
- insert(opts.merge(:safe => true))
49
- end
50
-
51
45
  def update(opts={}, update_doc=@doc)
52
46
  clear_changes if super
53
47
  end
54
48
 
55
- def update!(opts={}, update_doc=@doc)
56
- update(opts.merge(:safe => true), update_doc)
57
- end
58
-
59
49
  def save
60
50
  is_new ? insert : update
61
51
  end
data/lib/matic/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Matic
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/matic_spec.rb CHANGED
@@ -1,137 +1,184 @@
1
1
  require "spec_helper"
2
2
 
3
- describe "A matic model" do
3
+ describe "a mongomatic model that includes matic" do
4
4
 
5
5
  let(:person) { Person.new }
6
+ let(:book) { Book.new }
6
7
 
7
8
  it "has a collection first_name" do
8
9
  person.class.collection_name.should eql "people"
9
10
  end
10
11
 
11
- describe ".field" do
12
- it "defines a getter" do
13
- person["first_name"] = "John"
12
+ describe ".fields" do
14
13
 
15
- person.first_name.should eql "John"
16
- lambda { person.foo }.should raise_error NoMethodError
17
- end
14
+ context "when it is passed an array" do
18
15
 
19
- it "defines a setter" do
20
- person.first_name = "John"
16
+ it "defines a getter" do
17
+ person["first_name"] = "John"
21
18
 
22
- person["first_name"].should eql "John"
23
- lambda { person.foo= "bar" }.should raise_error NoMethodError
24
- end
25
- end
19
+ person.first_name.should eql "John"
20
+ lambda { person.foo }.should raise_error NoMethodError
21
+ end
22
+
23
+ it "defines a setter" do
24
+ person.first_name = "John"
26
25
 
27
- context "dirty tracking" do
26
+ person["first_name"].should eql "John"
27
+ lambda { person.foo= "bar" }.should raise_error NoMethodError
28
+ end
29
+
30
+ end
28
31
 
29
- shared_examples_for "a dirty-tracking command" do
32
+ context "when it is passed a hash" do
30
33
 
31
- it "marks a current change as previous" do
32
- person.first_name_changed?.should be_false
33
- person.previous_changes["first_name"].should eql [nil, "John"]
34
+ it "defines a getter" do
35
+ book["i"] = "9780485113358"
36
+ book.isbn.should eql "9780485113358"
34
37
 
35
- person.last_name_changed?.should be_false
36
- person.previous_changes["last_name"].should eql [nil, "Doe"]
38
+ book["a"] = ["Gilles Deleuze"]
39
+ book.authors.should eql ["Gilles Deleuze"]
37
40
  end
38
41
 
39
- it "does callbacks" do
40
- person.instance_variable_get(:@called_back).should be_true
42
+ it "defines a setter" do
43
+ book.isbn = "9780485113358"
44
+ book["i"].should eql "9780485113358"
45
+
46
+ book.authors = ["Gilles Deleuze"]
47
+ book["a"].should eql ["Gilles Deleuze"]
41
48
  end
42
49
 
50
+ it "stores documents with short field names" do
51
+ book.isbn = "9780485113358"
52
+ book.insert
53
+
54
+ book.instance_variable_get(:@doc).should have_key 'i'
55
+ end
43
56
  end
44
57
 
45
- shared_examples_for "a dirty object" do
58
+ end
46
59
 
47
- it "tells if an attribute changed" do
48
- person.first_name_changed?.should be_true
49
- person.last_name_changed?.should be_true
50
- end
60
+ shared_examples_for "a dirty-tracking command" do
51
61
 
52
- it "remembers changes to an attribute" do
53
- person.changes["first_name"].should eql [nil, "John"]
54
- person.changes["last_name"].should eql [nil, "Doe"]
55
- end
62
+ it "marks a current change as previous" do
63
+ person.first_name_changed?.should be_false
64
+ person.previous_changes["first_name"].should eql [nil, "John"]
56
65
 
66
+ person.last_name_changed?.should be_false
67
+ person.previous_changes["last_name"].should eql [nil, "Doe"]
57
68
  end
58
69
 
59
- context "when object is new" do
70
+ it "does callbacks" do
71
+ person.instance_variable_get(:@called_back).should be_true
72
+ end
60
73
 
61
- before do
62
- person.first_name = "John"
63
- person.last_name = "Doe"
64
- end
74
+ end
75
+
76
+ describe "a dirty-tracking setter" do
65
77
 
66
- it_behaves_like "a dirty object"
78
+ context "when an attribute is set" do
67
79
 
68
- describe "#insert" do
80
+ context "and its value has changed" do
69
81
 
70
- before { person.insert }
82
+ before do
83
+ person.first_name = "John"
84
+ end
71
85
 
72
- it_behaves_like "a dirty-tracking command"
86
+ it "marks the attribute as changed" do
87
+ person.first_name_changed?.should be_true
88
+ end
89
+
90
+ it "remembers changes to the attribute" do
91
+ person.changes["first_name"].should eql [nil, "John"]
92
+ end
73
93
 
74
94
  end
75
95
 
76
- describe "#insert!" do
96
+ context "and its value has not changed" do
77
97
 
78
- before { person.insert! }
98
+ before do
99
+ person.first_name = nil
100
+ end
79
101
 
80
- it_behaves_like "a dirty-tracking command"
102
+ it "does not mark the attribute as changed" do
103
+ person.first_name_changed?.should be_false
104
+ end
81
105
 
82
106
  end
83
107
 
84
- describe "#save" do
108
+ end
85
109
 
86
- before { person.save }
110
+ end
87
111
 
88
- it_behaves_like "a dirty-tracking command"
112
+ context "when object is new" do
89
113
 
90
- end
114
+ before do
115
+ person.first_name = "John"
116
+ person.last_name = "Doe"
117
+ end
118
+
119
+ describe "#insert" do
120
+
121
+ before { person.insert }
122
+
123
+ it_behaves_like "a dirty-tracking command"
91
124
 
92
125
  end
93
126
 
94
- context "when object is not new" do
127
+ describe "#insert!" do
95
128
 
96
- before do
97
- person.insert
98
- person.instance_variable_set(:@called_back, false)
99
- person.first_name = "John"
100
- person.last_name = "Doe"
101
- end
129
+ before { person.insert! }
102
130
 
103
- it_behaves_like "a dirty object"
131
+ it_behaves_like "a dirty-tracking command"
104
132
 
105
- describe "#update" do
133
+ end
106
134
 
107
- before { person.update }
135
+ describe "#save" do
108
136
 
109
- it_behaves_like "a dirty-tracking command"
137
+ before { person.save }
110
138
 
111
- end
139
+ it_behaves_like "a dirty-tracking command"
112
140
 
113
- describe "#update!" do
141
+ end
114
142
 
115
- before { person.update! }
143
+ end
116
144
 
117
- it_behaves_like "a dirty-tracking command"
145
+ context "when object is not new" do
118
146
 
119
- end
147
+ before do
148
+ person.insert
149
+ person.instance_variable_set(:@called_back, false)
150
+ person.first_name = "John"
151
+ person.last_name = "Doe"
152
+ end
153
+
154
+ describe "#update" do
155
+
156
+ before { person.update }
157
+
158
+ it_behaves_like "a dirty-tracking command"
120
159
 
121
160
  end
122
161
 
123
- context "when object is not valid" do
162
+ describe "#update!" do
124
163
 
125
- before do
126
- person.stub!(:valid?).and_return(false)
127
- person.first_name = "John"
128
- end
164
+ before { person.update! }
129
165
 
130
- it "does not clear changes" do
131
- person.save
132
- person.first_name_changed?.should be_true
133
- end
166
+ it_behaves_like "a dirty-tracking command"
167
+
168
+ end
169
+
170
+ end
171
+
172
+ context "when an invalid object is saved" do
173
+
174
+ before do
175
+ person.stub!(:valid?).and_return(false)
176
+ person.first_name = "John"
177
+ end
134
178
 
179
+ it "does not clear changes" do
180
+ person.save
181
+ person.first_name_changed?.should be_true
135
182
  end
136
183
 
137
184
  end
@@ -0,0 +1,8 @@
1
+ class Book < Mongomatic::Base
2
+ include Matic
3
+
4
+ fields :title => 't',
5
+ :authors => 'a',
6
+ :publisher => 'p',
7
+ :isbn => 'i'
8
+ end
@@ -1,8 +1,8 @@
1
1
  class Person < Mongomatic::Base
2
2
  include Matic
3
3
 
4
- field :first_name
5
- field :last_name
4
+ fields :first_name,
5
+ :last_name
6
6
 
7
7
  private
8
8
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Hakan Ensari
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-11 00:00:00 +00:00
18
+ date: 2010-11-12 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -130,6 +130,7 @@ files:
130
130
  - lib/matic/version.rb
131
131
  - matic.gemspec
132
132
  - spec/matic_spec.rb
133
+ - spec/models/book.rb
133
134
  - spec/models/person.rb
134
135
  - spec/spec_helper.rb
135
136
  - spec/support/mongomatic.rb
@@ -168,6 +169,7 @@ specification_version: 3
168
169
  summary: Mongomatic with attribute accessors and dirty tracking
169
170
  test_files:
170
171
  - spec/matic_spec.rb
172
+ - spec/models/book.rb
171
173
  - spec/models/person.rb
172
174
  - spec/spec_helper.rb
173
175
  - spec/support/mongomatic.rb