attr_json 0.7.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,16 +2,17 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "combustion", git: "https://github.com/pat/combustion.git"
6
- gem "rails", ">= 6.0.0.beta1", "< 6.1"
7
- gem "railties"
5
+ gem "combustion", "~> 1.0"
6
+ gem "rails", ">= 6.0.0", "< 6.1"
8
7
  gem "pg", "~> 1.0"
9
- gem "rspec-rails", "~> 3.7"
8
+ gem "rspec-rails", "~> 4.0"
10
9
  gem "simple_form", ">= 4.0"
11
10
  gem "cocoon", ">= 1.2"
12
11
  gem "jquery-rails"
12
+ gem "coffee-rails"
13
+ gem "sprockets-rails"
13
14
  gem "capybara", "~> 3.0"
14
- gem "webdrivers", "~> 3.0"
15
+ gem "webdrivers", "~> 4.0"
15
16
  gem "selenium-webdriver"
16
17
  gem "byebug"
17
18
 
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "combustion", "~> 1.0"
6
+ gem "rails", "~> 6.1.0"
7
+ gem "pg", "~> 1.0"
8
+ gem "rspec-rails", "~> 4.0"
9
+ gem "simple_form", ">= 4.0"
10
+ gem "cocoon", ">= 1.2"
11
+ gem "jquery-rails"
12
+ gem "coffee-rails"
13
+ gem "sprockets-rails"
14
+ gem "capybara", "~> 3.0"
15
+ gem "webdrivers", "~> 4.0"
16
+ gem "selenium-webdriver"
17
+ gem "byebug"
18
+
19
+ gemspec path: "../"
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "combustion", "~> 1.0"
6
+ gem "rails", "~> 7.0.0"
7
+ gem "pg", "~> 1.0"
8
+ gem "rspec-rails", "~> 4.0"
9
+ gem "simple_form", ">= 4.0"
10
+ gem "cocoon", ">= 1.2"
11
+ gem "jquery-rails"
12
+ gem "coffee-rails"
13
+ gem "sprockets-rails"
14
+ gem "capybara", "~> 3.0"
15
+ gem "webdrivers", "~> 4.0"
16
+ gem "selenium-webdriver"
17
+ gem "byebug"
18
+
19
+ gemspec path: "../"
@@ -2,18 +2,18 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "combustion", git: "https://github.com/pat/combustion.git"
6
- gem "rails", git: "https://github.com/rails/rails.git", branch: "master"
7
- gem "railties"
5
+ gem "combustion", "~> 1.0", github: "pat/combustion"
6
+ gem "rails", git: "https://github.com/rails/rails.git", branch: "main"
8
7
  gem "pg", "~> 1.0"
9
- gem "rspec-rails", "~> 3.7"
8
+ gem "rspec-rails", "~> 4.0"
10
9
  gem "simple_form", ">= 4.0"
11
10
  gem "cocoon", ">= 1.2"
12
11
  gem "jquery-rails"
12
+ gem "coffee-rails"
13
+ gem "sprockets-rails"
13
14
  gem "capybara", "~> 3.0"
14
- gem "webdrivers", "~> 3.0"
15
+ gem "webdrivers", "~> 4.0"
15
16
  gem "selenium-webdriver"
16
17
  gem "byebug"
17
- gem "coffee-rails"
18
18
 
19
19
  gemspec path: "../"
@@ -78,6 +78,12 @@
78
78
  @default != NO_DEFAULT_PROVIDED
79
79
  end
80
80
 
81
+ # Can be value or proc!
82
+ def default_argument
83
+ return nil unless has_default?
84
+ @default
85
+ end
86
+
81
87
  def provide_default!
82
88
  unless has_default?
83
89
  raise ArgumentError.new("This #{self.class.name} does not have a default defined!")
@@ -3,10 +3,20 @@ module AttrJson
3
3
  # and rails class_attribute. Instead, you set to new Config object
4
4
  # changed with {#merge}.
5
5
  class Config
6
- RECORD_ALLOWED_KEYS = %i{default_container_attribute default_accepts_nested_attributes}
7
- MODEL_ALLOWED_KEYS = %i{unknown_key}
6
+ RECORD_ALLOWED_KEYS = %i{
7
+ default_container_attribute
8
+ default_rails_attribute
9
+ default_accepts_nested_attributes
10
+ }
11
+
12
+ MODEL_ALLOWED_KEYS = %i{
13
+ unknown_key
14
+ bad_cast
15
+ }
16
+
8
17
  DEFAULTS = {
9
18
  default_container_attribute: "json_attributes",
19
+ default_rails_attribute: false,
10
20
  unknown_key: :raise
11
21
  }
12
22
 
@@ -7,6 +7,8 @@ require 'attr_json/attribute_definition/registry'
7
7
  require 'attr_json/type/model'
8
8
  require 'attr_json/model/cocoon_compat'
9
9
 
10
+ require 'attr_json/serialization_coder_from_type'
11
+
10
12
  module AttrJson
11
13
 
12
14
  # Meant for use in a plain class, turns it into an ActiveModel::Model
@@ -30,9 +32,39 @@ module AttrJson
30
32
  #
31
33
  # class Something
32
34
  # include AttrJson::Model
33
- # attr_json_config(unknown_key: :ignore)
35
+ # attr_json_config(unknown_key: :allow)
36
+ # #...
37
+ # end
38
+ #
39
+ # Similarly, trying to set a Model-valued attribute with an object that
40
+ # can't be cast to a Hash or Model at all will normally raise a
41
+ # AttrJson::Type::Model::BadCast error, but you can set config `bad_cast: :as_nil`
42
+ # to make it cast to nil, more like typical ActiveRecord cast.
43
+ #
44
+ # class Something
45
+ # include AttrJson::Model
46
+ # attr_json_config(bad_cast: :as_nil)
34
47
  # #...
35
48
  # end
49
+ #
50
+ # ## ActiveRecord `serialize`
51
+ #
52
+ # If you want to map a single AttrJson::Model to a json/jsonb column, you
53
+ # can use ActiveRecord `serialize` feature.
54
+ #
55
+ # https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
56
+ #
57
+ # We provide a simple shim to give you the right API for a "coder" for AR serialize:
58
+ #
59
+ # class ValueModel
60
+ # include AttrJson::Model
61
+ # attr_json :some_string, :string
62
+ # end
63
+ #
64
+ # class SomeModel < ApplicationRecord
65
+ # serialize :some_json_column, ValueModel.to_serialize_coder
66
+ # end
67
+ #
36
68
  module Model
37
69
  extend ActiveSupport::Concern
38
70
 
@@ -71,16 +103,27 @@ module AttrJson
71
103
  end
72
104
 
73
105
 
74
- # Like `.new`, but translate store keys in hash
106
+ # The inverse of model#serializable_hash -- re-hydrates a serialized hash to a model.
107
+ #
108
+ # Similar to `.new`, but translates things that need to be translated in deserialization,
109
+ # like store_keys, and properly calling deserialize on the underlying types.
110
+ #
111
+ # @example Model.new_from_serializable(hash)
75
112
  def new_from_serializable(attributes = {})
76
- attributes = attributes.transform_keys do |key|
113
+ attributes = attributes.collect do |key, value|
77
114
  # store keys in arguments get translated to attribute names on initialize.
78
115
  if attribute_def = self.attr_json_registry.store_key_lookup("", key.to_s)
79
- attribute_def.name.to_s
80
- else
81
- key
116
+ key = attribute_def.name.to_s
82
117
  end
83
- end
118
+
119
+ attr_type = self.attr_json_registry.has_attribute?(key) && self.attr_json_registry.type_for_attribute(key)
120
+ if attr_type
121
+ value = attr_type.deserialize(value)
122
+ end
123
+
124
+ [key, value]
125
+ end.to_h
126
+
84
127
  self.new(attributes)
85
128
  end
86
129
 
@@ -88,6 +131,21 @@ module AttrJson
88
131
  @type ||= AttrJson::Type::Model.new(self)
89
132
  end
90
133
 
134
+ def to_serialization_coder
135
+ @serialization_coder ||= AttrJson::SerializationCoderFromType.new(to_type)
136
+ end
137
+
138
+ # like the ActiveModel::Attributes method
139
+ def attribute_names
140
+ attr_json_registry.attribute_names
141
+ end
142
+
143
+ # like the ActiveModel::Attributes method, hash with name keys, and ActiveModel::Type values
144
+ def attribute_types
145
+ attribute_names.collect { |name| [name.to_s, attr_json_registry.type_for_attribute(name)]}.to_h
146
+ end
147
+
148
+
91
149
  # Type can be an instance of an ActiveModel::Type::Value subclass, or a symbol that will
92
150
  # be looked up in `ActiveModel::Type.lookup`
93
151
  #
@@ -130,27 +188,6 @@ module AttrJson
130
188
  end
131
189
  end
132
190
 
133
- # This should kind of be considered 'protected', but the semantics
134
- # of how we want to call it don't give us a visibility modifier that works.
135
- # Prob means refactoring called for. TODO?
136
- def fill_in_defaults(hash)
137
- # Only if we need to mutate it to add defaults, we'll dup it first. deep_dup not neccesary
138
- # since we're only modifying top-level here.
139
- duped = false
140
- attr_json_registry.definitions.each do |definition|
141
- if definition.has_default? && ! (hash.has_key?(definition.store_key.to_s) || hash.has_key?(definition.store_key.to_sym))
142
- unless duped
143
- hash = hash.dup
144
- duped = true
145
- end
146
-
147
- hash[definition.store_key] = definition.provide_default!
148
- end
149
- end
150
-
151
- hash
152
- end
153
-
154
191
  private
155
192
 
156
193
  # Define an anonymous module and include it, so can still be easily
@@ -166,11 +203,15 @@ module AttrJson
166
203
  end
167
204
 
168
205
  def initialize(attributes = {})
169
- if !attributes.respond_to?(:transform_keys)
170
- raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
171
- end
206
+ super
207
+
208
+ fill_in_defaults!
209
+ end
172
210
 
173
- super(self.class.fill_in_defaults(attributes))
211
+ # inspired by https://github.com/rails/rails/blob/8015c2c2cf5c8718449677570f372ceb01318a32/activemodel/lib/active_model/attributes.rb
212
+ def initialize_dup(other) # :nodoc:
213
+ @attributes = @attributes.deep_dup
214
+ super
174
215
  end
175
216
 
176
217
  def attributes
@@ -208,6 +249,11 @@ module AttrJson
208
249
  self.class.attr_json_registry.has_attribute?(str)
209
250
  end
210
251
 
252
+ # like the ActiveModel::Attributes method
253
+ def attribute_names
254
+ self.class.attribute_names
255
+ end
256
+
211
257
  # Override from ActiveModel::Serialization to #serialize
212
258
  # by type to make sure any values set directly on hash still
213
259
  # get properly type-serialized.
@@ -240,12 +286,9 @@ module AttrJson
240
286
  end
241
287
 
242
288
  # Two AttrJson::Model objects are equal if they are the same class
243
- # or one is a subclass of the other, AND their #attributes are equal.
244
- # TODO: Should we allow subclasses to be equal, or should they have to be the
245
- # exact same class?
289
+ # AND their #attributes are equal.
246
290
  def ==(other_object)
247
- (other_object.is_a?(self.class) || self.is_a?(other_object.class)) &&
248
- other_object.attributes == self.attributes
291
+ other_object.class == self.class && other_object.attributes == self.attributes
249
292
  end
250
293
 
251
294
  # ActiveRecord objects [have a](https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/nested_attributes.rb#L367-L374)
@@ -257,8 +300,25 @@ module AttrJson
257
300
  false
258
301
  end
259
302
 
303
+ # like ActiveModel::Attributes at
304
+ # https://github.com/rails/rails/blob/8015c2c2cf5c8718449677570f372ceb01318a32/activemodel/lib/active_model/attributes.rb#L120
305
+ #
306
+ # is not a full deep freeze
307
+ def freeze
308
+ attributes.freeze unless frozen?
309
+ super
310
+ end
311
+
260
312
  private
261
313
 
314
+ def fill_in_defaults!
315
+ self.class.attr_json_registry.definitions.each do |definition|
316
+ if definition.has_default? && !attributes.has_key?(definition.name.to_s)
317
+ self.send("#{definition.name.to_s}=", definition.provide_default!)
318
+ end
319
+ end
320
+ end
321
+
262
322
  def _attr_json_write(key, value)
263
323
  if attribute_def = self.class.attr_json_registry[key.to_sym]
264
324
  attributes[key.to_s] = attribute_def.cast(value)
@@ -270,7 +270,13 @@ module AttrJson
270
270
  # find it from currently declared attributes.
271
271
  # https://github.com/rails/rails/blob/6aa5cf03ea8232180ffbbae4c130b051f813c670/activemodel/lib/active_model/attribute_methods.rb#L463-L468
272
272
  def matched_attribute_method(method_name)
273
- matches = self.class.send(:attribute_method_matchers_matching, method_name)
273
+ if self.class.respond_to?(:attribute_method_patterns_matching, true)
274
+ # Rails 7.1+
275
+ matches = self.class.send(:attribute_method_patterns_matching, method_name)
276
+ else
277
+ matches = self.class.send(:attribute_method_matchers_matching, method_name)
278
+ end
279
+
274
280
  matches.detect do |match|
275
281
  registry.has_attribute?(match.attr_name)
276
282
  end
@@ -10,6 +10,20 @@ module AttrJson
10
10
  end
11
11
 
12
12
  def contains_relation
13
+ contains_relation_impl do |relation, query, params|
14
+ relation.where(query, params)
15
+ end
16
+ end
17
+
18
+ def contains_not_relation
19
+ contains_relation_impl do |relation, query, params|
20
+ relation.where.not(query, params)
21
+ end
22
+ end
23
+
24
+ protected
25
+
26
+ def contains_relation_impl
13
27
  result_relation = relation
14
28
 
15
29
  group_attributes_by_container.each do |container_attribute, attributes|
@@ -18,14 +32,12 @@ module AttrJson
18
32
  attributes.each do |key, value|
19
33
  add_to_param_hash!(param_hash, key, value)
20
34
  end
21
- result_relation = result_relation.where("#{relation.table_name}.#{container_attribute} @> (?)::jsonb", param_hash.to_json)
35
+ result_relation = yield(result_relation, "#{relation.table_name}.#{container_attribute} @> (?)::jsonb", param_hash.to_json)
22
36
  end
23
37
 
24
38
  result_relation
25
39
  end
26
40
 
27
- protected
28
-
29
41
  def merge_param_hash!(original, new)
30
42
  original.deep_merge!(new) do |key, old_val, new_val|
31
43
  if old_val.is_a?(Array) && old_val.first.is_a?(Hash) && new_val.is_a?(Array) && new_val.first.is_a?(Hash)
@@ -17,6 +17,8 @@ module AttrJson
17
17
  #
18
18
  # some_model.jsonb_contains(a_string: "foo").first
19
19
  #
20
+ # some_model.not_jsonb_contains(a_string: "bar").first
21
+ #
20
22
  # See more in {file:README} docs.
21
23
  module QueryScopes
22
24
  extend ActiveSupport::Concern
@@ -29,6 +31,10 @@ module AttrJson
29
31
  scope(:jsonb_contains, lambda do |attributes|
30
32
  QueryBuilder.new(self, attributes).contains_relation
31
33
  end)
34
+
35
+ scope(:not_jsonb_contains, lambda do |attributes|
36
+ QueryBuilder.new(self, attributes).contains_not_relation
37
+ end)
32
38
  end
33
39
  end
34
40
  end
@@ -47,7 +47,7 @@ module AttrJson
47
47
  when false, nil, ActiveModel::Type::Boolean::FALSE_VALUES
48
48
  false
49
49
  else
50
- if value.respond_to?(:to_i) && ( Numeric === value || value !~ /[^0-9]/ )
50
+ if value.respond_to?(:to_i) && ( Numeric === value || value.to_s !~ /[^0-9]/ )
51
51
  !value.to_i.zero?
52
52
  elsif value.respond_to?(:zero?)
53
53
  !value.zero?
@@ -119,10 +119,11 @@ module AttrJson
119
119
  # @option options [Boolean] :rails_attribute (false) Create an actual ActiveRecord
120
120
  # `attribute` for name param. A Rails attribute isn't needed for our functionality,
121
121
  # but registering thusly will let the type be picked up by simple_form and
122
- # other tools that may look for it via Rails attribute APIs.
122
+ # other tools that may look for it via Rails attribute APIs. Default can be changed
123
+ # with `attr_json_config(default_rails_attribute: true)`
123
124
  def attr_json(name, type, **options)
124
125
  options = {
125
- rails_attribute: false,
126
+ rails_attribute: self.attr_json_config.default_rails_attribute,
126
127
  validate: true,
127
128
  container_attribute: self.attr_json_config.default_container_attribute,
128
129
  accepts_nested_attributes: self.attr_json_config.default_accepts_nested_attributes
@@ -160,7 +161,21 @@ module AttrJson
160
161
  # We don't actually use this for anything, we provide our own covers. But registering
161
162
  # it with usual system will let simple_form and maybe others find it.
162
163
  if options[:rails_attribute]
163
- self.attribute name.to_sym, self.attr_json_registry.fetch(name).type
164
+ attr_json_definition = attr_json_registry[name]
165
+
166
+ attribute_args = attr_json_definition.has_default? ? { default: attr_json_definition.default_argument } : {}
167
+ self.attribute name.to_sym, attr_json_definition.type, **attribute_args
168
+
169
+ # Ensure that rails attributes tracker knows about value we just fetched
170
+ # for this particular attribute. Yes, we are registering an after_find for each
171
+ # attr_json registered with rails_attribute:true, using the `name` from above under closure. .
172
+ after_find do
173
+ value = public_send(name)
174
+ if value && has_attribute?(name.to_sym)
175
+ write_attribute(name.to_sym, value)
176
+ self.send(:clear_attribute_changes, [name.to_sym])
177
+ end
178
+ end
164
179
  end
165
180
 
166
181
  _attr_jsons_module.module_eval do
@@ -173,6 +188,7 @@ module AttrJson
173
188
  # this simple way.
174
189
 
175
190
  define_method("#{name}=") do |value|
191
+ super(value) if defined?(super)
176
192
  attribute_def = self.class.attr_json_registry.fetch(name.to_sym)
177
193
  public_send(attribute_def.container_attribute)[attribute_def.store_key] = attribute_def.cast(value)
178
194
  end
@@ -0,0 +1,40 @@
1
+ module AttrJson
2
+
3
+ # A little wrapper to provide an object that provides #dump and #load method for use
4
+ # as a coder second-argument for [ActiveRecord Serialization](https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html),
5
+ # that simply delegates to #serialize and #deserialize from a ActiveModel::Type object.
6
+ #
7
+ # Created to be used with an AttrJson::Model type (AttrJson::Type::Model), but hypothetically
8
+ # could be a shim from anything with serialize/deserialize to dump/load instead.
9
+ #
10
+ # class ValueModel
11
+ # include AttrJson::Model
12
+ # attr_json :some_string, :string
13
+ # end
14
+ #
15
+ # class SomeModel < ApplicationRecord
16
+ # serialize :some_json_column, ValueModel.to_serialize_coder
17
+ # end
18
+ #
19
+ # Note when used with an AttrJson::Model, it will dump/load from a HASH, not a
20
+ # string. It assumes it's writing to a Json(b) column that wants/provides hashes,
21
+ # not strings.
22
+ class SerializationCoderFromType
23
+ attr_reader :type
24
+ def initialize(type)
25
+ @type = type
26
+ end
27
+
28
+ # Dump and load methods to support ActiveRecord Serialization
29
+ # too.
30
+ def dump(value)
31
+ type.serialize(value)
32
+ end
33
+
34
+ # Dump and load methods to support ActiveRecord Serialization
35
+ # too. https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
36
+ def load(value)
37
+ type.deserialize(value)
38
+ end
39
+ end
40
+ end
@@ -7,6 +7,7 @@ module AttrJson
7
7
  # You create one with AttrJson::Model::Type.new(attr_json_model_class),
8
8
  # but normally that's only done in AttrJson::Model.to_type, there isn't
9
9
  # an anticipated need to create from any other place.
10
+ #
10
11
  class Model < ::ActiveModel::Type::Value
11
12
  class BadCast < ArgumentError ; end
12
13
 
@@ -31,15 +32,17 @@ module AttrJson
31
32
  # to_hash is actually the 'implicit' conversion, it really is a hash
32
33
  # even though it isn't is_a?(Hash), try to_hash first before to_h,
33
34
  # the explicit conversion.
34
- model.new_from_serializable(v.to_hash)
35
+ model.new(v.to_hash)
35
36
  elsif v.respond_to?(:to_h)
36
37
  # TODO Maybe we ought not to do this on #to_h?
37
- model.new_from_serializable(v.to_h)
38
+ model.new(v.to_h)
39
+ elsif model.attr_json_config.bad_cast == :as_nil
40
+ # This was originally default behavior, to be like existing ActiveRecord
41
+ # which kind of silently does this for non-castable basic values. That
42
+ # ended up being confusing in the basic case, so now we raise by default,
43
+ # but this is still configurable.
44
+ nil
38
45
  else
39
- # Bad input. Originally we were trying to return nil, to be like
40
- # existing ActiveRecord which kind of silently does a basic value
41
- # with null input. But that ended up making things confusing, let's
42
- # just raise.
43
46
  raise BadCast.new("Can not cast from #{v.inspect} to #{self.type}")
44
47
  end
45
48
  end
@@ -50,12 +53,36 @@ module AttrJson
50
53
  elsif v.kind_of?(model)
51
54
  v.serializable_hash
52
55
  else
53
- cast(v).serializable_hash
56
+ (cast_v = cast(v)) && cast_v.serializable_hash
54
57
  end
55
58
  end
56
59
 
57
60
  def deserialize(v)
58
- cast(v)
61
+ if v.nil?
62
+ # important to stay nil instead of empty object, because they
63
+ # are different things.
64
+ v
65
+ elsif v.kind_of? model
66
+ v
67
+ elsif v.respond_to?(:to_hash)
68
+ # to_hash is actually the 'implicit' conversion, it really is a hash
69
+ # even though it isn't is_a?(Hash), try to_hash first before to_h,
70
+ # the explicit conversion.
71
+ model.new_from_serializable(v.to_hash)
72
+ elsif v.respond_to?(:to_h)
73
+ # TODO Maybe we ought not to do this on #to_h? especially here in deserialize?
74
+ model.new_from_serializable(v.to_h)
75
+ elsif model.attr_json_config.bad_cast == :as_nil
76
+ # TODO should we have different config value for bad_deserialize vs bad_cast?
77
+
78
+ # This was originally default behavior, to be like existing ActiveRecord
79
+ # which kind of silently does this for non-castable basic values. That
80
+ # ended up being confusing in the basic case, so now we raise by default,
81
+ # but this is still configurable.
82
+ nil
83
+ else
84
+ raise BadCast.new("Can not cast from #{v.inspect} to #{self.type}")
85
+ end
59
86
  end
60
87
 
61
88
  # these guys are definitely mutable, so we need this.
@@ -51,6 +51,8 @@ module AttrJson
51
51
  # MyRecord.jsonb_contains(author: { name: "foo", type: "Corporation"})
52
52
  # MyRecord.jsonb_contains(author: Corporation.new(name: "foo"))
53
53
  #
54
+ # Additionally, there is not_jsonb_contains, which creates the same query terms like jsonb_contains, but negated.
55
+ #
54
56
  class PolymorphicModel < ActiveModel::Type::Value
55
57
  class TypeError < ::TypeError ; end
56
58
 
@@ -112,6 +114,11 @@ module AttrJson
112
114
  end
113
115
 
114
116
  def serialize(v)
117
+ return nil if v.nil?
118
+
119
+ # if it's not already a model cast it to a model if possible (eg it's a hash)
120
+ v = cast(v)
121
+
115
122
  model_name = v.class.name
116
123
  type = type_for_model_name(model_name)
117
124
 
@@ -1,3 +1,3 @@
1
1
  module AttrJson
2
- VERSION = "0.7.0"
2
+ VERSION = "1.5.0"
3
3
  end
data/lib/attr_json.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "attr_json/version"
2
2
 
3
3
  require "active_record"
4
- require "active_record/connection_adapters/postgresql_adapter"
5
4
 
6
5
  require 'attr_json/config'
7
6
  require 'attr_json/record'