hstore_accessor 0.3.1 → 0.3.2

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