hstore_accessor 0.3.1 → 0.3.2
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.
- checksums.yaml +4 -4
- data/lib/hstore_accessor.rb +10 -12
- data/lib/hstore_accessor/version.rb +1 -1
- data/spec/hstore_accessor_spec.rb +52 -28
- data/spec/spec_helper.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 562c366519112f79fb774a0a0d95ee3a67eb102c
|
4
|
+
data.tar.gz: b4a6a2aeb1095f3fa29bd92e349dc26442f9ca34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6576cf6f73c0f602b8f825d326d09e3dd1d03eab7e6e1f4ed298484a33f96d0754cbeca846cffb13c45562bd3fac09bfbd8596c781cecfcb77fb3d70ed699909
|
7
|
+
data.tar.gz: 1bec8ccdd58531c62333ff9b9ab6b8276741b65b5406312052be78e178d02a7c250d803383b81a9aa14aa4fdab21bf8e9aa78637d2493b6b343689fef113275d
|
data/lib/hstore_accessor.rb
CHANGED
@@ -3,42 +3,41 @@ require "active_support"
|
|
3
3
|
require "active_record"
|
4
4
|
|
5
5
|
module HstoreAccessor
|
6
|
+
extend ActiveSupport::Concern
|
6
7
|
|
7
8
|
InvalidDataTypeError = Class.new(StandardError)
|
8
9
|
|
9
10
|
VALID_TYPES = [:string, :integer, :float, :time, :boolean, :array, :hash]
|
10
11
|
|
11
|
-
SEPARATOR = "
|
12
|
+
SEPARATOR = "||;||"
|
12
13
|
|
13
14
|
DEFAULT_SERIALIZER = ->(value) { value.to_s }
|
14
|
-
DEFAULT_DESERIALIZER =
|
15
|
+
DEFAULT_DESERIALIZER = DEFAULT_SERIALIZER
|
15
16
|
|
16
17
|
SERIALIZERS = {
|
17
|
-
:array => -> value { (value && value.join(SEPARATOR)) ||
|
18
|
-
:hash => -> value { (value && value.to_json) ||
|
18
|
+
:array => -> value { (value && value.join(SEPARATOR)) || nil },
|
19
|
+
:hash => -> value { (value && value.to_json) || nil },
|
19
20
|
:time => -> value { value.to_i },
|
20
21
|
:boolean => -> value { (value == true).to_s }
|
21
22
|
}
|
22
23
|
|
23
24
|
DESERIALIZERS = {
|
24
|
-
:array => -> value { (value && value.split(SEPARATOR)) ||
|
25
|
-
:hash => -> value { (value && JSON.parse(value)) ||
|
25
|
+
:array => -> value { (value && value.split(SEPARATOR)) || nil },
|
26
|
+
:hash => -> value { (value && JSON.parse(value)) || nil },
|
26
27
|
:integer => -> value { value.to_i },
|
27
28
|
:float => -> value { value.to_f },
|
28
29
|
:time => -> value { Time.at(value.to_i) },
|
29
30
|
:boolean => -> value { value == "true" }
|
30
31
|
}
|
31
32
|
|
32
|
-
def self.included(base)
|
33
|
-
base.extend(ClassMethods)
|
34
|
-
end
|
35
|
-
|
36
33
|
def serialize(type, value, serializer=nil)
|
34
|
+
return nil if value.nil?
|
37
35
|
serializer ||= (SERIALIZERS[type] || DEFAULT_SERIALIZER)
|
38
36
|
serializer.call(value)
|
39
37
|
end
|
40
38
|
|
41
39
|
def deserialize(type, value, deserializer=nil)
|
40
|
+
return nil if value.nil?
|
42
41
|
deserializer ||= (DESERIALIZERS[type] || DEFAULT_DESERIALIZER)
|
43
42
|
deserializer.call(value)
|
44
43
|
end
|
@@ -46,7 +45,6 @@ module HstoreAccessor
|
|
46
45
|
module ClassMethods
|
47
46
|
|
48
47
|
def hstore_accessor(hstore_attribute, fields)
|
49
|
-
|
50
48
|
fields.each do |key, type|
|
51
49
|
|
52
50
|
raise InvalidDataTypeError unless VALID_TYPES.include?(type)
|
@@ -57,7 +55,7 @@ module HstoreAccessor
|
|
57
55
|
end
|
58
56
|
|
59
57
|
define_method(key) do
|
60
|
-
value = send(hstore_attribute) && send(hstore_attribute)[key.to_s]
|
58
|
+
value = send(hstore_attribute) && send(hstore_attribute).with_indifferent_access[key.to_s]
|
61
59
|
deserialize(type, value)
|
62
60
|
end
|
63
61
|
|
@@ -1,15 +1,18 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "active_support/all"
|
3
3
|
|
4
|
+
FIELDS = {
|
5
|
+
color: :string,
|
6
|
+
price: :integer,
|
7
|
+
weight: :float,
|
8
|
+
popular: :boolean,
|
9
|
+
build_timestamp: :time,
|
10
|
+
tags: :array,
|
11
|
+
reviews: :hash
|
12
|
+
}
|
13
|
+
|
4
14
|
class Product < ActiveRecord::Base
|
5
|
-
hstore_accessor :options,
|
6
|
-
color: :string,
|
7
|
-
price: :integer,
|
8
|
-
weight: :float,
|
9
|
-
popular: :boolean,
|
10
|
-
build_timestamp: :time,
|
11
|
-
tags: :array,
|
12
|
-
reviews: :hash
|
15
|
+
hstore_accessor :options, FIELDS
|
13
16
|
end
|
14
17
|
|
15
18
|
describe HstoreAccessor do
|
@@ -18,14 +21,14 @@ describe HstoreAccessor do
|
|
18
21
|
|
19
22
|
let(:product) { Product.new }
|
20
23
|
|
21
|
-
|
22
|
-
|
24
|
+
FIELDS.keys.each do |field|
|
25
|
+
it "creates a getter for the hstore field: #{field}" do
|
23
26
|
expect(product).to respond_to(field)
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
FIELDS.keys.each do |field|
|
31
|
+
it "creates a setter for the hstore field: #{field}=" do
|
29
32
|
expect(product).to respond_to(:"#{field}=")
|
30
33
|
end
|
31
34
|
end
|
@@ -41,6 +44,25 @@ describe HstoreAccessor do
|
|
41
44
|
|
42
45
|
end
|
43
46
|
|
47
|
+
context "nil values" do
|
48
|
+
let!(:timestamp) { Time.now }
|
49
|
+
let!(:product) { Product.new }
|
50
|
+
let!(:product_a) { Product.create(color: "green", price: 10, weight: 10.1, tags: ["tag1", "tag2", "tag3"], popular: true, build_timestamp: (timestamp - 10.days)) }
|
51
|
+
|
52
|
+
FIELDS.keys.each do |field|
|
53
|
+
it "reponds with nil when #{field} is not set" do
|
54
|
+
expect(product.send(field)).to be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
FIELDS.keys.each do |field|
|
59
|
+
it "reponds with nil when #{field} is set back to nil after being set initially" do
|
60
|
+
product_a.send("#{field}=", nil)
|
61
|
+
expect(product_a.send(field)).to be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
44
66
|
describe "scopes" do
|
45
67
|
|
46
68
|
let!(:timestamp) { Time.now }
|
@@ -158,6 +180,24 @@ describe HstoreAccessor do
|
|
158
180
|
expect(product.color).to eq "blue"
|
159
181
|
end
|
160
182
|
|
183
|
+
it "allows access to bulk set values via string before saving" do
|
184
|
+
product.options = {
|
185
|
+
"color" => "blue",
|
186
|
+
"price" => 120
|
187
|
+
}
|
188
|
+
expect(product.color).to eq "blue"
|
189
|
+
expect(product.price).to eq 120
|
190
|
+
end
|
191
|
+
|
192
|
+
it "allows access to bulk set values via :symbols before saving" do
|
193
|
+
product.options = {
|
194
|
+
color: "blue",
|
195
|
+
price: 120
|
196
|
+
}
|
197
|
+
expect(product.color).to eq "blue"
|
198
|
+
expect(product.price).to eq 120
|
199
|
+
end
|
200
|
+
|
161
201
|
it "correctly stores integer values" do
|
162
202
|
product.price = 468
|
163
203
|
product.save
|
@@ -179,14 +219,6 @@ describe HstoreAccessor do
|
|
179
219
|
expect(product.tags).to eq ["household", "living room", "kitchen"]
|
180
220
|
end
|
181
221
|
|
182
|
-
it "returns an empty array if an array value is not set" do
|
183
|
-
expect(Product.new.tags).to eq []
|
184
|
-
product.tags = nil
|
185
|
-
product.save
|
186
|
-
product.reload
|
187
|
-
expect(product.tags).to eq []
|
188
|
-
end
|
189
|
-
|
190
222
|
it "correctly stores hash values" do
|
191
223
|
product.reviews = { "user_123" => "4 stars", "user_994" => "3 stars" }
|
192
224
|
product.save
|
@@ -194,14 +226,6 @@ describe HstoreAccessor do
|
|
194
226
|
expect(product.reviews).to eq({ "user_123" => "4 stars", "user_994" => "3 stars" })
|
195
227
|
end
|
196
228
|
|
197
|
-
it "returns an empty hash if a hash value is not set" do
|
198
|
-
expect(Product.new.reviews).to eq({})
|
199
|
-
product.reviews = nil
|
200
|
-
product.save
|
201
|
-
product.reload
|
202
|
-
expect(product.reviews).to eq({})
|
203
|
-
end
|
204
|
-
|
205
229
|
it "correctly stores time values" do
|
206
230
|
timestamp = Time.now - 10.days
|
207
231
|
product.build_timestamp = timestamp
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,7 @@ ActiveRecord::Base.establish_connection(
|
|
6
6
|
username: "root"
|
7
7
|
)
|
8
8
|
|
9
|
-
ActiveRecord::Base.connection.execute("CREATE EXTENSION hstore;") rescue
|
9
|
+
ActiveRecord::Base.connection.execute("CREATE EXTENSION hstore;") rescue ActiveRecord::StatementInvalid
|
10
10
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS products;")
|
11
11
|
|
12
12
|
ActiveRecord::Base.connection.create_table(:products) do |t|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hstore_accessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Hirn
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: pg
|