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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a5d9f17253e89a2b07c07a55c190d7c2a04b8ae
4
- data.tar.gz: d285866bb3f67915215e7266d3de5d3f5a65a35d
3
+ metadata.gz: 562c366519112f79fb774a0a0d95ee3a67eb102c
4
+ data.tar.gz: b4a6a2aeb1095f3fa29bd92e349dc26442f9ca34
5
5
  SHA512:
6
- metadata.gz: cf306876687e4430a522deb04adf10ccf166c4a3d6362e0daf0bdc119cd07345c265646e1f33131bd690f5b34292f1cb6908f51e94a7b15bf5cbcd1153fc5663
7
- data.tar.gz: 7717387fe1db69737e6fc73c5cdb2d6967876ac027f5bc840b970ea846e1737b40d1e943b5d1e6aaea965e8652d000fb99ddd8fdaa32c80c8b0f905444e8acf3
6
+ metadata.gz: 6576cf6f73c0f602b8f825d326d09e3dd1d03eab7e6e1f4ed298484a33f96d0754cbeca846cffb13c45562bd3fac09bfbd8596c781cecfcb77fb3d70ed699909
7
+ data.tar.gz: 1bec8ccdd58531c62333ff9b9ab6b8276741b65b5406312052be78e178d02a7c250d803383b81a9aa14aa4fdab21bf8e9aa78637d2493b6b343689fef113275d
@@ -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 = ->(value) { value.to_s }
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,3 +1,3 @@
1
1
  module HstoreAccessor
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -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
- it "creates getters for the hstore fields" do
22
- [:color, :price, :weight, :tags, :reviews].each do |field|
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
- it "creates setters for the hstore fields" do
28
- [:color, :price, :weight, :tags, :reviews].each do |field|
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
@@ -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 PG::Error
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.1
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-06-12 00:00:00.000000000 Z
13
+ date: 2013-07-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pg