hstore_accessor 0.6.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +41 -0
- data/Appraisals +11 -0
- data/Gemfile +1 -5
- data/README.md +128 -57
- data/Rakefile +8 -2
- data/gemfiles/activerecord_4.0.gemfile +11 -0
- data/gemfiles/activerecord_4.1.gemfile +11 -0
- data/gemfiles/activerecord_4.2.gemfile +11 -0
- data/hstore_accessor.gemspec +16 -10
- data/lib/hstore_accessor.rb +10 -4
- data/lib/hstore_accessor/active_record_4.2/type_helpers.rb +34 -0
- data/lib/hstore_accessor/{time_helper.rb → active_record_<_4.2/time_helper.rb} +2 -4
- data/lib/hstore_accessor/active_record_<_4.2/type_helpers.rb +42 -0
- data/lib/hstore_accessor/macro.rb +110 -46
- data/lib/hstore_accessor/serialization.rb +39 -27
- data/lib/hstore_accessor/version.rb +1 -1
- data/spec/hstore_accessor_spec.rb +281 -85
- data/spec/spec_helper.rb +14 -0
- metadata +85 -17
- data/lib/hstore_accessor/type_helpers.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be6414ac167ae2ee47c461f887f5e38557e9bc1f
|
4
|
+
data.tar.gz: 30c0619e2c650ab109adc4a47af914326dc6a699
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc93bf29866e627e137c90b557acbe22f360ba6f1c3dcf847fc1aa1187beee2d68d8dc40cd80d81c052f6742afc8d8bb76c8b320b12d6859521965f4d8aa05d2
|
7
|
+
data.tar.gz: 00c0d0fbecbb399f0553128ff1dc5686a9d022031783db4faa4aa4b60860aa554433050f623bc01381885cbe0fcf689d999a7f9e6c9a34d17c6c4d7e8eaa407a
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- Rakefile
|
4
|
+
Lint/SpaceBeforeFirstArg:
|
5
|
+
Enabled: false
|
6
|
+
Lint/UnusedBlockArgument:
|
7
|
+
Enabled: false
|
8
|
+
Lint/UnusedMethodArgument:
|
9
|
+
Enabled: false
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Enabled: false
|
12
|
+
Metrics/ClassLength:
|
13
|
+
Enabled: false
|
14
|
+
Metrics/CyclomaticComplexity:
|
15
|
+
Enabled: false
|
16
|
+
Metrics/LineLength:
|
17
|
+
Enabled: false
|
18
|
+
Metrics/MethodLength:
|
19
|
+
Enabled: false
|
20
|
+
Metrics/PerceivedComplexity:
|
21
|
+
Enabled: false
|
22
|
+
Style/AlignParameters:
|
23
|
+
Enabled: false
|
24
|
+
Style/ClassAndModuleChildren:
|
25
|
+
Enabled: false
|
26
|
+
Style/Documentation:
|
27
|
+
Enabled: false
|
28
|
+
Style/FileName:
|
29
|
+
Enabled: false
|
30
|
+
Style/GuardClause:
|
31
|
+
Enabled: false
|
32
|
+
Style/IndentHash:
|
33
|
+
Enabled: false
|
34
|
+
Style/RescueModifier:
|
35
|
+
Enabled: false
|
36
|
+
Style/SignalException:
|
37
|
+
Enabled: false
|
38
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
39
|
+
Enabled: false
|
40
|
+
Style/StringLiterals:
|
41
|
+
EnforcedStyle: double_quotes
|
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,17 +2,33 @@
|
|
2
2
|
|
3
3
|
# HstoreAccessor
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
Hstore Accessor allows you to treat fields on an hstore column as though they were actual columns being picked up by ActiveRecord. This is especially handy when trying to avoid sparse columns while making use of [single table inheritence](#single-table-inheritance). Hstore Accessor currently supports ActiveRecord versions 4.0, 4.1, and 4.2.
|
6
|
+
|
7
|
+
## Table of Contents
|
8
|
+
|
9
|
+
* [Installation](#installation)
|
10
|
+
* [Setup](#setup)
|
11
|
+
* [ActiveRecord methods generated for fields](#activerecord-methods-generated-for-fields)
|
12
|
+
* [Scopes](#scopes)
|
13
|
+
* [String Fields](#string-fields)
|
14
|
+
* [Integer, Float, and Decimal Fields](#integer-float-decimal-fields)
|
15
|
+
* [Datetime Fields](#datetime-fields)
|
16
|
+
* [Date Fields](#date-fields)
|
17
|
+
* [Array Fields](#array-fields)
|
18
|
+
* [Boolean Fields](#boolean-fields)
|
19
|
+
* [Single Table Inheritence](#single-table-inheritance)
|
20
|
+
* [Upgrading](#upgrading)
|
21
|
+
* [Contributing](#contributing)
|
22
|
+
- [Basics](#basics)
|
23
|
+
- [Developing Locally](#developing-locally)
|
10
24
|
|
11
25
|
## Installation
|
12
26
|
|
13
27
|
Add this line to your application's Gemfile:
|
14
28
|
|
15
|
-
|
29
|
+
```ruby
|
30
|
+
gem "hstore_accessor"
|
31
|
+
```
|
16
32
|
|
17
33
|
And then execute:
|
18
34
|
|
@@ -22,47 +38,47 @@ Or install it yourself as:
|
|
22
38
|
|
23
39
|
$ gem install hstore_accessor
|
24
40
|
|
25
|
-
##
|
26
|
-
|
27
|
-
### Setup
|
41
|
+
## Setup
|
28
42
|
|
29
43
|
The `hstore_accessor` method accepts the name of the hstore column you'd
|
30
44
|
like to use and a hash with keys representing fields and values
|
31
45
|
indicating the type to be stored in that field. The available types
|
32
|
-
are: `string`, `integer`, `float`, `
|
46
|
+
are: `string`, `integer`, `float`, `decimal`, `datetime`, `date`, `boolean`, `array`, and `hash`. It is available on an class that inherits from `ActiveRecord::Base`.
|
33
47
|
|
34
48
|
```ruby
|
35
49
|
class Product < ActiveRecord::Base
|
36
|
-
|
37
50
|
hstore_accessor :options,
|
38
51
|
color: :string,
|
39
52
|
weight: :integer,
|
40
53
|
price: :float,
|
41
|
-
built_at: :
|
42
|
-
|
43
|
-
|
44
|
-
|
54
|
+
built_at: :datetime,
|
55
|
+
build_date: :date,
|
56
|
+
tags: :array, # deprecated
|
57
|
+
ratings: :hash # deprecated
|
58
|
+
miles: :decimal
|
45
59
|
end
|
46
60
|
```
|
47
61
|
|
48
62
|
Now you can interact with the fields stored in the hstore directly.
|
49
63
|
|
50
64
|
```ruby
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
65
|
+
product = Product.new
|
66
|
+
product.color = "green"
|
67
|
+
product.weight = 34
|
68
|
+
product.price = 99.95
|
69
|
+
product.built_at = Time.now - 10.days
|
70
|
+
product.build_date = Date.today
|
71
|
+
product.popular = true
|
72
|
+
product.tags = %w(housewares kitchen) # deprecated
|
73
|
+
product.ratings = { user_a: 3, user_b: 4 } # deprecated
|
74
|
+
product.miles = 3.14
|
59
75
|
```
|
60
76
|
|
61
77
|
Reading these fields works as well.
|
62
78
|
|
63
79
|
```ruby
|
64
|
-
|
65
|
-
|
80
|
+
product.color # => "green"
|
81
|
+
product.price # => 99.95
|
66
82
|
```
|
67
83
|
|
68
84
|
In order to reduce the storage overhead of hstore keys (especially when
|
@@ -82,20 +98,42 @@ Additionally, dirty tracking is implemented in the same way that normal
|
|
82
98
|
`ActiveRecord` fields work.
|
83
99
|
|
84
100
|
```ruby
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
```
|
101
|
+
product.color #=> "green"
|
102
|
+
product.color = "blue"
|
103
|
+
product.changed? #=> true
|
104
|
+
product.color_changed? #=> true
|
105
|
+
product.color_was #=> "green"
|
106
|
+
product.color_change #=> ["green", "blue"]
|
107
|
+
```
|
108
|
+
|
109
|
+
## ActiveRecord methods generated for fields
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
class Product < ActiveRecord::Base
|
113
|
+
hstore_accessor :data, field: :string
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
* `field`
|
118
|
+
* `field=`
|
119
|
+
* `field?`
|
120
|
+
* `field_changed?`
|
121
|
+
* `field_was`
|
122
|
+
* `field_change`
|
123
|
+
* `reset_field!`
|
124
|
+
* `restore_field!`
|
125
|
+
* `field_will_change!`
|
92
126
|
|
93
|
-
|
127
|
+
Overriding methods is supported, with access to the original Hstore Accessor implementation available via `super`.
|
128
|
+
|
129
|
+
Additionally, there is also `hstore_metadata_for_<fields>` on both the class and instances. `column_for_attribute` will also return a column object for an Hstore Accessor defined field. If you're using ActiveRecord 4.2, `type_for_attribute` will return a type object for Hstore Accessor defined fields the same as it does for actual columns.
|
130
|
+
|
131
|
+
## Scopes
|
94
132
|
|
95
133
|
The `hstore_accessor` macro also creates scopes for `string`, `integer`,
|
96
|
-
`float`, `time`, `boolean`, and `array` fields.
|
134
|
+
`float`, `decimal`, `time`, `date`, `boolean`, and `array` fields.
|
97
135
|
|
98
|
-
|
136
|
+
### String Fields
|
99
137
|
|
100
138
|
For `string` types, a `with_<key>` scope is created which checks for
|
101
139
|
equality.
|
@@ -104,21 +142,21 @@ equality.
|
|
104
142
|
Product.with_color("green")
|
105
143
|
```
|
106
144
|
|
107
|
-
|
145
|
+
### Integer, Float, Decimal Fields
|
108
146
|
|
109
|
-
For `integer` and `
|
147
|
+
For `integer`, `float` and `decimal` types five scopes are created:
|
110
148
|
|
111
149
|
```ruby
|
112
|
-
Product.price_lt(240.00)
|
113
|
-
Product.price_lte(240.00)
|
114
|
-
Product.price_eq(240.00)
|
115
|
-
Product.price_gte(240.00)
|
116
|
-
Product.price_gt(240.00)
|
150
|
+
Product.price_lt(240.00) # price less than
|
151
|
+
Product.price_lte(240.00) # price less than or equal to
|
152
|
+
Product.price_eq(240.00) # price equal to
|
153
|
+
Product.price_gte(240.00) # price greater than or equal to
|
154
|
+
Product.price_gt(240.00) # price greater than
|
117
155
|
```
|
118
156
|
|
119
|
-
|
157
|
+
### Datetime Fields
|
120
158
|
|
121
|
-
For `
|
159
|
+
For `datetime` fields, three scopes are created:
|
122
160
|
|
123
161
|
```ruby
|
124
162
|
Product.built_at_before(Time.now) # built before the given time
|
@@ -126,30 +164,42 @@ Product.built_at_eq(Time.now - 10.days) # built at an exact time
|
|
126
164
|
Product.built_at_after(Time.now - 4.days) # built after the given time
|
127
165
|
```
|
128
166
|
|
129
|
-
|
167
|
+
### Date Fields
|
168
|
+
|
169
|
+
For `date` fields, three scopes are created:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Product.build_date_before(Date.today) # built before the given date
|
173
|
+
Product.build_date_eq(Date.today - 10.days) # built at an exact date
|
174
|
+
Product.built_date_after(Date.today - 4.days) # built after the given date
|
175
|
+
```
|
176
|
+
|
177
|
+
### Array Fields
|
178
|
+
|
179
|
+
*Note: the array field type is deprecated. It is available in version 0.9.0 but not > 1.0.0*
|
130
180
|
|
131
181
|
For `array` types, two scopes are created:
|
132
182
|
|
133
183
|
```ruby
|
134
|
-
Product.tags_eq(
|
135
|
-
Product.tags_contains("kitchen")
|
136
|
-
Product.tags_contains(
|
184
|
+
Product.tags_eq(%w(housewares kitchen)) # tags equaling
|
185
|
+
Product.tags_contains("kitchen") # tags containing a single value
|
186
|
+
Product.tags_contains(%w(housewares kitchen)) # tags containing a number of values
|
137
187
|
```
|
138
188
|
|
139
|
-
|
189
|
+
### Boolean Fields
|
140
190
|
|
141
191
|
Two scopes are created for `boolean` fields:
|
142
192
|
|
143
193
|
```ruby
|
144
|
-
Product.is_popular
|
145
|
-
Product.not_popular
|
194
|
+
Product.is_popular # => when populer is set to true
|
195
|
+
Product.not_popular # => when populer is set to false
|
146
196
|
```
|
147
197
|
|
148
198
|
Predicate methods are also available on instances:
|
149
199
|
|
150
200
|
```ruby
|
151
201
|
product = Product.new(popular: true)
|
152
|
-
product.popular?
|
202
|
+
product.popular? # => true
|
153
203
|
```
|
154
204
|
|
155
205
|
### Single-table Inheritance
|
@@ -209,11 +259,32 @@ individual fields in an `hstore` column.
|
|
209
259
|
This approach was originally concieved by Joe Hirn in [this blog
|
210
260
|
post](http://www.devmynd.com/blog/2013-3-single-table-inheritance-hstore-lovely-combination).
|
211
261
|
|
262
|
+
## Upgrading
|
263
|
+
Upgrading from version 0.6.0 to 0.9.0 should be fairly painless. If you were previously using a `time` type fields, simply change it to `datetime` like so:
|
212
264
|
|
213
|
-
|
265
|
+
```ruby
|
266
|
+
# Before...
|
267
|
+
hstore_accessor :data, published_at: :time
|
268
|
+
# After...
|
269
|
+
hstore_accessor :data, published_at: :datetime
|
270
|
+
```
|
271
|
+
|
272
|
+
While the `array` and `hash` types are available in version 0.9.0, they are deprecated and are not available in 1.0.0.
|
214
273
|
|
215
|
-
|
274
|
+
## Contributing
|
275
|
+
### Basics
|
276
|
+
1. [Fork it](https://github.com/devmynd/hstore_accessor/fork)
|
216
277
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
217
|
-
3.
|
218
|
-
4.
|
219
|
-
5.
|
278
|
+
3. Write code _and_ tests
|
279
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
280
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
281
|
+
6. Create new Pull Request
|
282
|
+
|
283
|
+
### Developing Locally
|
284
|
+
Before you make your pull requests, please make sure you style is in line with our Rubocop settings and that all of the tests pass.
|
285
|
+
|
286
|
+
1. `bundle install`
|
287
|
+
2. `appraisal install`
|
288
|
+
3. Make sure Postgres is installed and running
|
289
|
+
4. `appraisal rspec` to run all the tests
|
290
|
+
5. `rubocop` to check for style
|
data/Rakefile
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
1
3
|
require "bundler/gem_tasks"
|
2
|
-
require
|
3
|
-
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
|
4
7
|
RSpec::Core::RakeTask.new
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
10
|
+
task(default: [:rubocop, :spec])
|
data/hstore_accessor.gemspec
CHANGED
@@ -6,10 +6,10 @@ require "hstore_accessor/version"
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "hstore_accessor"
|
8
8
|
spec.version = HstoreAccessor::VERSION
|
9
|
-
spec.authors = ["Joe Hirn", "Cory Stephenson", "JC Grubbs"]
|
10
|
-
spec.email = ["joe@devmynd.com", "cory@devmynd.com", "jc@devmynd.com"]
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
9
|
+
spec.authors = ["Joe Hirn", "Cory Stephenson", "JC Grubbs", "Tony Coconate", "Michael Crismali"]
|
10
|
+
spec.email = ["joe@devmynd.com", "cory@devmynd.com", "jc@devmynd.com", "me@tonycoconate.com", "michael@devmynd.com"]
|
11
|
+
spec.description = "Adds typed hstore backed fields to an ActiveRecord model."
|
12
|
+
spec.summary = "Adds typed hstore backed fields to an ActiveRecord model."
|
13
13
|
spec.homepage = "http://github.com/devmynd/hstore_accessor"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,12 +18,18 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "
|
21
|
+
spec.add_dependency "activerecord", ">= 4.0.0"
|
22
22
|
|
23
|
-
spec.add_development_dependency "
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.
|
25
|
-
spec.add_development_dependency "rake"
|
26
|
-
spec.add_development_dependency "rspec"
|
27
|
-
spec.add_development_dependency "pry"
|
23
|
+
spec.add_development_dependency "appraisal"
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
28
25
|
spec.add_development_dependency "database_cleaner"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "pry-doc"
|
28
|
+
spec.add_development_dependency "pry-nav"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.1.0"
|
31
|
+
spec.add_development_dependency "rubocop"
|
32
|
+
spec.add_development_dependency "shoulda-matchers"
|
33
|
+
|
34
|
+
spec.post_install_message = "Please note that the `array` and `hash` types will no longer be supported in version 1.0.0"
|
29
35
|
end
|