superstore 2.4.4 → 2.5.0
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 +5 -5
- data/.travis.yml +4 -6
- data/Gemfile +2 -3
- data/{Gemfile-rails4.2 → Gemfile.rails6} +2 -3
- data/README.md +4 -34
- data/lib/superstore.rb +17 -18
- data/lib/superstore/adapters/abstract_adapter.rb +1 -27
- data/lib/superstore/adapters/jsonb_adapter.rb +4 -132
- data/lib/superstore/associations.rb +6 -1
- data/lib/superstore/associations/association.rb +6 -0
- data/lib/superstore/associations/association_scope.rb +20 -0
- data/lib/superstore/associations/belongs_to.rb +3 -1
- data/lib/superstore/associations/has_many.rb +15 -2
- data/lib/superstore/associations/reflection.rb +8 -2
- data/lib/superstore/attribute_assignment.rb +7 -0
- data/lib/superstore/attribute_methods.rb +1 -109
- data/lib/superstore/attribute_methods/primary_key.rb +20 -11
- data/lib/superstore/attributes.rb +13 -0
- data/lib/superstore/base.rb +8 -33
- data/lib/superstore/core.rb +7 -65
- data/lib/superstore/model_schema.rb +35 -0
- data/lib/superstore/persistence.rb +31 -115
- data/lib/superstore/railtie.rb +3 -11
- data/lib/superstore/relation/scrolling.rb +48 -0
- data/lib/superstore/timestamp.rb +13 -0
- data/lib/superstore/types.rb +11 -9
- data/lib/superstore/types/array_type.rb +3 -7
- data/lib/superstore/types/boolean_type.rb +7 -12
- data/lib/superstore/types/date_range_type.rb +7 -0
- data/lib/superstore/types/date_type.rb +7 -10
- data/lib/superstore/types/float_type.rb +3 -11
- data/lib/superstore/types/geo_point_type.rb +30 -0
- data/lib/superstore/types/integer_range_type.rb +19 -0
- data/lib/superstore/types/integer_type.rb +8 -14
- data/lib/superstore/types/json_type.rb +1 -1
- data/lib/superstore/types/range_type.rb +51 -0
- data/lib/superstore/types/string_type.rb +4 -4
- data/lib/superstore/types/time_type.rb +10 -8
- data/superstore.gemspec +4 -3
- data/test/support/jsonb.rb +3 -1
- data/test/support/models.rb +8 -5
- data/test/test_helper.rb +6 -2
- data/test/unit/adapters/adapter_test.rb +1 -3
- data/test/unit/associations/belongs_to_test.rb +1 -1
- data/test/unit/associations/has_many_test.rb +10 -2
- data/test/unit/attribute_methods/dirty_test.rb +8 -19
- data/test/unit/attribute_methods/primary_key_test.rb +1 -1
- data/test/unit/attribute_methods_test.rb +10 -22
- data/test/unit/{attribute_methods/typecasting_test.rb → attributes_test.rb} +13 -39
- data/test/unit/base_test.rb +4 -0
- data/test/unit/caching_test.rb +1 -1
- data/test/unit/callbacks_test.rb +4 -4
- data/test/unit/core_test.rb +9 -19
- data/test/unit/persistence_test.rb +17 -54
- data/test/unit/{scope/batches_test.rb → relation/scrolling_test.rb} +9 -5
- data/test/unit/serialization_test.rb +10 -2
- data/test/unit/{timestamps_test.rb → timestamp_test.rb} +5 -5
- data/test/unit/types/array_type_test.rb +3 -18
- data/test/unit/types/boolean_type_test.rb +7 -21
- data/test/unit/types/date_range_type_test.rb +28 -0
- data/test/unit/types/date_type_test.rb +15 -6
- data/test/unit/types/float_type_test.rb +4 -19
- data/test/unit/types/geo_point_type_test.rb +24 -0
- data/test/unit/types/integer_range_type_test.rb +28 -0
- data/test/unit/types/integer_type_test.rb +7 -16
- data/test/unit/types/string_type_test.rb +9 -13
- data/test/unit/types/time_type_test.rb +17 -11
- data/test/unit/validations_test.rb +2 -2
- metadata +39 -39
- data/lib/superstore/attribute_methods/definition.rb +0 -17
- data/lib/superstore/attribute_methods/dirty.rb +0 -52
- data/lib/superstore/attribute_methods/typecasting.rb +0 -53
- data/lib/superstore/caching.rb +0 -13
- data/lib/superstore/callbacks.rb +0 -29
- data/lib/superstore/connection.rb +0 -24
- data/lib/superstore/errors.rb +0 -10
- data/lib/superstore/inspect.rb +0 -25
- data/lib/superstore/model.rb +0 -38
- data/lib/superstore/schema.rb +0 -20
- data/lib/superstore/scope.rb +0 -73
- data/lib/superstore/scope/batches.rb +0 -27
- data/lib/superstore/scope/finder_methods.rb +0 -51
- data/lib/superstore/scope/query_methods.rb +0 -52
- data/lib/superstore/scoping.rb +0 -30
- data/lib/superstore/timestamps.rb +0 -19
- data/lib/superstore/type.rb +0 -16
- data/lib/superstore/types/base_type.rb +0 -23
- data/lib/superstore/validations.rb +0 -44
- data/test/unit/attribute_methods/definition_test.rb +0 -16
- data/test/unit/inspect_test.rb +0 -26
- data/test/unit/schema_test.rb +0 -15
- data/test/unit/scope/finder_methods_test.rb +0 -62
- data/test/unit/scope/query_methods_test.rb +0 -37
- data/test/unit/scoping_test.rb +0 -7
- data/test/unit/types/base_type_test.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 69f3fe9607d8df59438f381a38fa0068f7a7435666bc1a79588cbe5914896b59
|
|
4
|
+
data.tar.gz: 7da54acc35f5126576c35e6574e41b7cffd0eca9221ce5784948471eababe617
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c7dcb613c89611211e5610bd991156e6ee4fb5f5e0f87f4f0b820ca1ed6555a26de8d618c7da14efa5b10dce9ae5b43aa732ee51d81ca8603be88bd231e63052
|
|
7
|
+
data.tar.gz: db48bc7c88e0ab91dcc376f212b866556f0189b52841aa6491ff5a71dba83b4eaaae4e9b74c57ff759d42b6a20954571265979ea7d854de118dff589803a59e4
|
data/.travis.yml
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
-
rvm:
|
|
3
|
-
|
|
4
|
-
sudo: required
|
|
5
|
-
dist: trusty
|
|
2
|
+
rvm: 2.6.3
|
|
3
|
+
dist: xenial
|
|
6
4
|
cache: bundler
|
|
7
5
|
gemfile:
|
|
8
6
|
- Gemfile
|
|
9
|
-
- Gemfile
|
|
7
|
+
- Gemfile.rails6
|
|
10
8
|
addons:
|
|
11
|
-
postgresql: 9.
|
|
9
|
+
postgresql: 9.6
|
|
12
10
|
services:
|
|
13
11
|
- postgresql
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Superstore
|
|
2
|
-
[](http://travis-ci.org/data-axle/superstore)
|
|
3
3
|
[](https://codeclimate.com/github/data-axle/superstore)
|
|
4
4
|
[](https://rubygems.org/gems/superstore)
|
|
5
5
|
|
|
@@ -15,27 +15,18 @@ Superstore requires PostgreSQL 9.5 or above.
|
|
|
15
15
|
Add the following to the `Gemfile`:
|
|
16
16
|
|
|
17
17
|
```ruby
|
|
18
|
-
gem 'pg'
|
|
19
18
|
gem 'superstore'
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
Add a `config/superstore.yml`:
|
|
23
|
-
|
|
24
|
-
```yaml
|
|
25
|
-
development:
|
|
26
|
-
adapter: jsonb
|
|
27
|
-
```
|
|
28
|
-
|
|
29
21
|
Superstore will share the existing ActiveRecord database connection.
|
|
30
22
|
|
|
31
23
|
## Defining Models
|
|
32
24
|
|
|
33
25
|
```ruby
|
|
34
26
|
class Widget < Superstore::Base
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
array :colors, unique: true
|
|
27
|
+
attribute :name, type: :string
|
|
28
|
+
attribute :price, type: :integer
|
|
29
|
+
attribute :colors, type: :array
|
|
39
30
|
|
|
40
31
|
validates :name, presence: :true
|
|
41
32
|
|
|
@@ -69,24 +60,3 @@ widget.price_was
|
|
|
69
60
|
widget.save
|
|
70
61
|
widget.save!
|
|
71
62
|
```
|
|
72
|
-
|
|
73
|
-
## Finding records
|
|
74
|
-
|
|
75
|
-
```ruby
|
|
76
|
-
widget = Widget.find(uuid)
|
|
77
|
-
widget = Widget.first
|
|
78
|
-
widgets = Widget.all
|
|
79
|
-
Widget.find_each do |widget|
|
|
80
|
-
# Codez
|
|
81
|
-
end
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Scoping
|
|
85
|
-
|
|
86
|
-
Some lightweight scoping features are available:
|
|
87
|
-
|
|
88
|
-
```ruby
|
|
89
|
-
Widget.where('color' => 'red')
|
|
90
|
-
Widget.select(['name', 'color'])
|
|
91
|
-
Widget.limit(10)
|
|
92
|
-
```
|
data/lib/superstore.rb
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
require 'active_support/all'
|
|
2
2
|
require 'active_model'
|
|
3
|
+
require 'active_record'
|
|
3
4
|
require 'global_id/identification'
|
|
4
|
-
require 'oj'
|
|
5
|
-
require 'superstore/errors'
|
|
6
5
|
|
|
7
6
|
module Superstore
|
|
8
7
|
extend ActiveSupport::Autoload
|
|
@@ -10,30 +9,21 @@ module Superstore
|
|
|
10
9
|
autoload :AttributeMethods
|
|
11
10
|
autoload :Base
|
|
12
11
|
autoload :Associations
|
|
13
|
-
autoload :
|
|
14
|
-
autoload :
|
|
12
|
+
autoload :AttributeAssignment
|
|
13
|
+
autoload :Attributes
|
|
15
14
|
autoload :Connection
|
|
16
15
|
autoload :Core
|
|
17
16
|
autoload :Identity
|
|
18
|
-
autoload :
|
|
19
|
-
autoload :
|
|
17
|
+
autoload :Inheritance
|
|
18
|
+
autoload :ModelSchema
|
|
20
19
|
autoload :Persistence
|
|
21
|
-
autoload :
|
|
22
|
-
autoload :CassandraSchema
|
|
23
|
-
autoload :Scope
|
|
24
|
-
autoload :Scoping
|
|
25
|
-
autoload :Timestamps
|
|
26
|
-
autoload :Type
|
|
27
|
-
autoload :Validations
|
|
20
|
+
autoload :Timestamp
|
|
28
21
|
|
|
29
22
|
module AttributeMethods
|
|
30
23
|
extend ActiveSupport::Autoload
|
|
31
24
|
|
|
32
25
|
eager_autoload do
|
|
33
|
-
autoload :Definition
|
|
34
|
-
autoload :Dirty
|
|
35
26
|
autoload :PrimaryKey
|
|
36
|
-
autoload :Typecasting
|
|
37
27
|
end
|
|
38
28
|
end
|
|
39
29
|
|
|
@@ -42,13 +32,13 @@ module Superstore
|
|
|
42
32
|
|
|
43
33
|
autoload :AbstractAdapter
|
|
44
34
|
autoload :JsonbAdapter
|
|
45
|
-
autoload :CassandraAdapter
|
|
46
35
|
end
|
|
47
36
|
|
|
48
37
|
module Associations
|
|
49
38
|
extend ActiveSupport::Autoload
|
|
50
39
|
|
|
51
40
|
autoload :Association
|
|
41
|
+
autoload :AssociationScope
|
|
52
42
|
autoload :Reflection
|
|
53
43
|
autoload :BelongsTo
|
|
54
44
|
autoload :HasMany
|
|
@@ -64,16 +54,25 @@ module Superstore
|
|
|
64
54
|
end
|
|
65
55
|
end
|
|
66
56
|
|
|
57
|
+
module Relation
|
|
58
|
+
extend ActiveSupport::Autoload
|
|
59
|
+
|
|
60
|
+
autoload :Scrolling
|
|
61
|
+
end
|
|
62
|
+
|
|
67
63
|
module Types
|
|
68
64
|
extend ActiveSupport::Autoload
|
|
69
65
|
|
|
70
|
-
autoload :BaseType
|
|
71
66
|
autoload :ArrayType
|
|
72
67
|
autoload :BooleanType
|
|
73
68
|
autoload :DateType
|
|
69
|
+
autoload :DateRangeType
|
|
74
70
|
autoload :FloatType
|
|
71
|
+
autoload :GeoPointType
|
|
75
72
|
autoload :IntegerType
|
|
73
|
+
autoload :IntegerRangeType
|
|
76
74
|
autoload :JsonType
|
|
75
|
+
autoload :RangeType
|
|
77
76
|
autoload :StringType
|
|
78
77
|
autoload :TimeType
|
|
79
78
|
end
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
module Superstore
|
|
2
2
|
module Adapters
|
|
3
3
|
class AbstractAdapter
|
|
4
|
-
|
|
5
|
-
def initialize(config)
|
|
6
|
-
@config = config
|
|
7
|
-
@batch_statements = nil
|
|
4
|
+
def initialize
|
|
8
5
|
end
|
|
9
6
|
|
|
10
7
|
# Read records from a instance of Superstore::Scope
|
|
@@ -22,29 +19,6 @@ module Superstore
|
|
|
22
19
|
# Delete rows by an array of ids
|
|
23
20
|
def delete(table, ids) # abstract
|
|
24
21
|
end
|
|
25
|
-
|
|
26
|
-
def execute_batch(statements) # abstract
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def batching?
|
|
30
|
-
!@batch_statements.nil?
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def batch
|
|
34
|
-
@batch_statements = []
|
|
35
|
-
yield
|
|
36
|
-
execute_batch(@batch_statements) if @batch_statements.any?
|
|
37
|
-
ensure
|
|
38
|
-
@batch_statements = nil
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def execute_batchable(statement)
|
|
42
|
-
if @batch_statements
|
|
43
|
-
@batch_statements << statement
|
|
44
|
-
else
|
|
45
|
-
execute statement
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
22
|
end
|
|
49
23
|
end
|
|
50
24
|
end
|
|
@@ -4,86 +4,6 @@ require 'pg'
|
|
|
4
4
|
module Superstore
|
|
5
5
|
module Adapters
|
|
6
6
|
class JsonbAdapter < AbstractAdapter
|
|
7
|
-
class QueryBuilder
|
|
8
|
-
def initialize(adapter, scope)
|
|
9
|
-
@adapter = adapter
|
|
10
|
-
@scope = scope
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def to_query
|
|
14
|
-
[
|
|
15
|
-
"SELECT #{select_string}",
|
|
16
|
-
from_string,
|
|
17
|
-
where_string,
|
|
18
|
-
order_string,
|
|
19
|
-
limit_string
|
|
20
|
-
].delete_if(&:blank?) * ' '
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def from_string
|
|
24
|
-
"FROM #{@scope.klass.table_name}"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def select_string
|
|
28
|
-
if @scope.select_values.empty?
|
|
29
|
-
'*'
|
|
30
|
-
elsif @scope.select_values == [@adapter.primary_key_column]
|
|
31
|
-
@adapter.primary_key_column
|
|
32
|
-
else
|
|
33
|
-
selects = @scope.select_values.map { |key| "#{@adapter.quote(key)},document->#{@adapter.quote(key)}" }
|
|
34
|
-
"#{@adapter.primary_key_column}, json_build_object(#{selects * ','}) as document"
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def where_string
|
|
39
|
-
wheres = where_values_as_strings
|
|
40
|
-
|
|
41
|
-
if @scope.id_values.any?
|
|
42
|
-
wheres << @adapter.create_ids_where_clause(@scope.id_values)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
if wheres.any?
|
|
46
|
-
"WHERE #{wheres * ' AND '}"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def order_string
|
|
51
|
-
if @scope.order_values.any?
|
|
52
|
-
orders = @scope.order_values.join(', ')
|
|
53
|
-
"ORDER BY #{orders}"
|
|
54
|
-
elsif @scope.id_values.many?
|
|
55
|
-
id_orders = @scope.id_values.map { |id| "ID=#{@adapter.quote(id)} DESC" }.join(',')
|
|
56
|
-
"ORDER BY #{id_orders}"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def limit_string
|
|
61
|
-
if @scope.limit_value
|
|
62
|
-
"LIMIT #{@scope.limit_value}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def where_values_as_strings
|
|
67
|
-
@scope.where_values.map do |where_value|
|
|
68
|
-
if where_value.is_a?(Hash)
|
|
69
|
-
key = where_value.keys.first
|
|
70
|
-
value = where_value.values.first
|
|
71
|
-
|
|
72
|
-
if value.nil?
|
|
73
|
-
"(document->>'#{key}') IS NULL"
|
|
74
|
-
elsif value.is_a?(Array)
|
|
75
|
-
typecasted_values = value.map { |v| "'#{v}'" }.join(',')
|
|
76
|
-
"document->>'#{key}' IN (#{typecasted_values})"
|
|
77
|
-
else
|
|
78
|
-
"document->>'#{key}' = '#{value}'"
|
|
79
|
-
end
|
|
80
|
-
else
|
|
81
|
-
where_value
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
7
|
PRIMARY_KEY_COLUMN = 'id'.freeze
|
|
88
8
|
def primary_key_column
|
|
89
9
|
PRIMARY_KEY_COLUMN
|
|
@@ -105,39 +25,10 @@ module Superstore
|
|
|
105
25
|
connection.execute statement
|
|
106
26
|
end
|
|
107
27
|
|
|
108
|
-
def to_ids(scope)
|
|
109
|
-
statement = QueryBuilder.new(self, scope.select(primary_key_column)).to_query
|
|
110
|
-
connection.select_values(statement)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def select(scope)
|
|
114
|
-
statement = QueryBuilder.new(self, scope).to_query
|
|
115
|
-
|
|
116
|
-
connection.execute(statement).each do |result|
|
|
117
|
-
yield result[primary_key_column], Oj.compat_load(result['document'])
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def scroll(scope, batch_size)
|
|
122
|
-
statement = QueryBuilder.new(self, scope).to_query
|
|
123
|
-
cursor_name = "cursor_#{SecureRandom.hex(6)}"
|
|
124
|
-
fetch_sql = "FETCH FORWARD #{batch_size} FROM #{cursor_name}"
|
|
125
|
-
|
|
126
|
-
connection.transaction do
|
|
127
|
-
connection.execute "DECLARE #{cursor_name} NO SCROLL CURSOR FOR (#{statement})"
|
|
128
|
-
|
|
129
|
-
while (batch = connection.execute(fetch_sql)).any?
|
|
130
|
-
batch.each do |result|
|
|
131
|
-
yield result[primary_key_column], Oj.compat_load(result['document'])
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
28
|
def insert(table, id, attributes)
|
|
138
29
|
not_nil_attributes = attributes.reject { |key, value| value.nil? }
|
|
139
30
|
statement = "INSERT INTO #{table} (#{primary_key_column}, document) VALUES (#{quote(id)}, #{to_quoted_jsonb(not_nil_attributes)})"
|
|
140
|
-
|
|
31
|
+
execute statement
|
|
141
32
|
end
|
|
142
33
|
|
|
143
34
|
def update(table, id, attributes)
|
|
@@ -157,31 +48,13 @@ module Superstore
|
|
|
157
48
|
|
|
158
49
|
statement = "UPDATE #{table} SET document = #{value_update} WHERE #{primary_key_column} = #{quote(id)}"
|
|
159
50
|
|
|
160
|
-
|
|
51
|
+
execute statement
|
|
161
52
|
end
|
|
162
53
|
|
|
163
54
|
def delete(table, ids)
|
|
164
55
|
statement = "DELETE FROM #{table} WHERE #{create_ids_where_clause(ids)}"
|
|
165
56
|
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def execute_batch(statements)
|
|
170
|
-
connection.transaction do
|
|
171
|
-
execute(statements * ";\n")
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def create_table(table_name, options = {})
|
|
176
|
-
ActiveRecord::Migration.create_table table_name, id: false do |t|
|
|
177
|
-
t.string :id, null: false
|
|
178
|
-
t.jsonb :document, null: false
|
|
179
|
-
end
|
|
180
|
-
connection.execute "ALTER TABLE \"#{table_name}\" ADD CONSTRAINT #{table_name}_pkey PRIMARY KEY (id)"
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def drop_table(table_name)
|
|
184
|
-
ActiveRecord::Migration.drop_table table_name
|
|
57
|
+
execute statement
|
|
185
58
|
end
|
|
186
59
|
|
|
187
60
|
def create_ids_where_clause(ids)
|
|
@@ -204,9 +77,8 @@ module Superstore
|
|
|
204
77
|
"ARRAY[#{quoted_fields}]"
|
|
205
78
|
end
|
|
206
79
|
|
|
207
|
-
OJ_OPTIONS = {mode: :compat}
|
|
208
80
|
def to_quoted_jsonb(data)
|
|
209
|
-
"#{quote(
|
|
81
|
+
"#{quote(JSON.generate(data))}::JSONB"
|
|
210
82
|
end
|
|
211
83
|
end
|
|
212
84
|
end
|
|
@@ -2,7 +2,12 @@ module Superstore
|
|
|
2
2
|
module Associations
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
included do
|
|
6
|
+
include ActiveRecord::Associations
|
|
7
|
+
extend ClassOverrides
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassOverrides
|
|
6
11
|
# === Options
|
|
7
12
|
# [:class_name]
|
|
8
13
|
# Use if the class cannot be inferred from the association
|
|
@@ -7,6 +7,7 @@ module Superstore
|
|
|
7
7
|
def initialize(owner, reflection)
|
|
8
8
|
@owner = owner
|
|
9
9
|
@reflection = reflection
|
|
10
|
+
reset
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def association_class
|
|
@@ -33,6 +34,11 @@ module Superstore
|
|
|
33
34
|
def loaded!
|
|
34
35
|
@loaded = true
|
|
35
36
|
end
|
|
37
|
+
|
|
38
|
+
def reset
|
|
39
|
+
@loaded = false
|
|
40
|
+
@target = nil
|
|
41
|
+
end
|
|
36
42
|
end
|
|
37
43
|
end
|
|
38
44
|
end
|