torque-postgresql 3.3.0 → 3.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/torque/postgresql/associations/belongs_to_many_association.rb +2 -2
- data/lib/torque/postgresql/associations/preloader/loader_query.rb +7 -7
- data/lib/torque/postgresql/schema_cache/schema_reflection.rb +1 -1
- data/lib/torque/postgresql/schema_cache.rb +5 -3
- data/lib/torque/postgresql/version.rb +1 -1
- data/spec/schema.rb +9 -9
- data/spec/tests/belongs_to_many_spec.rb +42 -1
- data/spec/tests/distinct_on_spec.rb +1 -1
- data/spec/tests/has_many_spec.rb +41 -0
- data/spec/tests/relation_spec.rb +1 -1
- data/spec/tests/table_inheritance_spec.rb +15 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a40ad54958c3355dabba2edfdf5fb0a833e9f2eeb16eb6aa680e522a93fe5cd
|
4
|
+
data.tar.gz: 32b7d2b052b475996081fedcfd265ed45f75aa115941269e93d26f6b88fe97e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36f81c4fd169d0e2dd164f17ba28ee6b6efb7e656609b45471216c5ec7119dc1f567e9864616420786a985d1a1630da681b423c7f9bff035fcf347c518dce14
|
7
|
+
data.tar.gz: de52240614a54984891c727edb19811ab67037a30f5f284bf4e5f9ce7e29e0afd19e9cc24897fdd2a1d060f6fc3d3ac466a39a812c3f975ec4c91b7bf51b0ec2
|
@@ -12,9 +12,9 @@ module Torque
|
|
12
12
|
## CUSTOM
|
13
13
|
def ids_reader
|
14
14
|
if loaded?
|
15
|
-
target.pluck(reflection.
|
15
|
+
target.pluck(reflection.active_record_primary_key)
|
16
16
|
elsif !target.empty?
|
17
|
-
load_target.pluck(reflection.
|
17
|
+
load_target.pluck(reflection.active_record_primary_key)
|
18
18
|
else
|
19
19
|
stale_state || column_default_value
|
20
20
|
end
|
@@ -11,20 +11,20 @@ module Torque
|
|
11
11
|
|
12
12
|
def load_records_for_keys(keys, &block)
|
13
13
|
condition = query_condition_for(keys)
|
14
|
+
return super if condition.nil?
|
15
|
+
|
14
16
|
scope.where(condition).load(&block)
|
15
17
|
end
|
16
18
|
|
17
19
|
def query_condition_for(keys)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
{ association_key_name => keys }
|
23
|
-
end
|
20
|
+
return unless connected_through_array?
|
21
|
+
|
22
|
+
value = scope.cast_for_condition(foreign_column, keys.to_a)
|
23
|
+
scope.table[association_key_name].overlaps(value)
|
24
24
|
end
|
25
25
|
|
26
26
|
def connected_through_array?
|
27
|
-
foreign_column.array?
|
27
|
+
!association_key_name.is_a?(Array) && foreign_column.array?
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -4,7 +4,7 @@ module Torque
|
|
4
4
|
module PostgreSQL
|
5
5
|
module SchemaReflection
|
6
6
|
def add_model_name(connection, table_name, model)
|
7
|
-
cache(connection).add_model_name(table_name, model)
|
7
|
+
cache(connection).add_model_name(connection, table_name, model)
|
8
8
|
end
|
9
9
|
|
10
10
|
def dependencies(connection, table_name)
|
@@ -97,9 +97,11 @@ module Torque
|
|
97
97
|
end
|
98
98
|
|
99
99
|
# A way to manually add models name so it doesn't need the lookup method
|
100
|
-
def add_model_name(
|
101
|
-
|
102
|
-
|
100
|
+
def add_model_name(*args)
|
101
|
+
model, *source = args.reverse
|
102
|
+
return unless data_source_exists?(*source.reverse) && model.is_a?(Class)
|
103
|
+
|
104
|
+
@data_sources_model_names[source.first] = model
|
103
105
|
end
|
104
106
|
|
105
107
|
# Get all the tables that the given one inherits from
|
data/spec/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
version =
|
13
|
+
version = 3
|
14
14
|
|
15
15
|
return if ActiveRecord::Migrator.current_version == version
|
16
16
|
ActiveRecord::Schema.define(version: version) do
|
@@ -77,14 +77,14 @@ ActiveRecord::Schema.define(version: version) do
|
|
77
77
|
create_table "texts", force: :cascade do |t|
|
78
78
|
t.integer "user_id"
|
79
79
|
t.string "content"
|
80
|
-
t.enum "conflict",
|
80
|
+
t.enum "conflict", enum_type: :conflicts
|
81
81
|
end
|
82
82
|
|
83
83
|
create_table "comments", force: :cascade do |t|
|
84
|
-
t.integer "user_id",
|
84
|
+
t.integer "user_id", null: false
|
85
85
|
t.integer "comment_id"
|
86
86
|
t.integer "video_id"
|
87
|
-
t.text "content",
|
87
|
+
t.text "content", null: false
|
88
88
|
t.string "kind"
|
89
89
|
t.index ["user_id"], name: "index_comments_on_user_id", using: :btree
|
90
90
|
t.index ["comment_id"], name: "index_comments_on_comment_id", using: :btree
|
@@ -92,7 +92,7 @@ ActiveRecord::Schema.define(version: version) do
|
|
92
92
|
|
93
93
|
create_table "courses", force: :cascade do |t|
|
94
94
|
t.integer "category_id"
|
95
|
-
t.string "title",
|
95
|
+
t.string "title", null: false
|
96
96
|
t.interval "duration"
|
97
97
|
t.enum "types", enum_type: :types, array: true
|
98
98
|
t.datetime "created_at", null: false
|
@@ -108,7 +108,7 @@ ActiveRecord::Schema.define(version: version) do
|
|
108
108
|
t.integer "activity_id"
|
109
109
|
t.string "title"
|
110
110
|
t.text "content"
|
111
|
-
t.enum "status",
|
111
|
+
t.enum "status", enum_type: :content_status
|
112
112
|
t.index ["author_id"], name: "index_posts_on_author_id", using: :btree
|
113
113
|
end
|
114
114
|
|
@@ -120,8 +120,8 @@ ActiveRecord::Schema.define(version: version) do
|
|
120
120
|
end
|
121
121
|
|
122
122
|
create_table "users", force: :cascade do |t|
|
123
|
-
t.string "name",
|
124
|
-
t.enum "role",
|
123
|
+
t.string "name", null: false
|
124
|
+
t.enum "role", enum_type: :roles, default: :visitor
|
125
125
|
t.datetime "created_at", null: false
|
126
126
|
t.datetime "updated_at", null: false
|
127
127
|
end
|
@@ -137,7 +137,7 @@ ActiveRecord::Schema.define(version: version) do
|
|
137
137
|
t.integer "author_id"
|
138
138
|
t.string "title"
|
139
139
|
t.boolean "active"
|
140
|
-
t.enum "kind",
|
140
|
+
t.enum "kind", enum_type: :types
|
141
141
|
t.datetime "created_at", null: false
|
142
142
|
t.datetime "updated_at", null: false
|
143
143
|
end
|
@@ -400,7 +400,7 @@ RSpec.describe 'BelongsToMany' do
|
|
400
400
|
let(:player) { Class.new(ActiveRecord::Base) }
|
401
401
|
let(:other) { player.create }
|
402
402
|
|
403
|
-
# TODO: Set as a
|
403
|
+
# TODO: Set as a shared example
|
404
404
|
before do
|
405
405
|
connection.create_table(:players, id: :uuid) { |t| t.string :name }
|
406
406
|
connection.create_table(:games, id: :uuid) { |t| t.uuid :player_ids, array: true }
|
@@ -440,4 +440,45 @@ RSpec.describe 'BelongsToMany' do
|
|
440
440
|
expect { query.load }.not_to raise_error
|
441
441
|
end
|
442
442
|
end
|
443
|
+
|
444
|
+
context 'using custom keys' do
|
445
|
+
let(:connection) { ActiveRecord::Base.connection }
|
446
|
+
let(:post) { Post }
|
447
|
+
let(:tag) { Tag }
|
448
|
+
let(:tags) { %w[a b c].map { |id| create(:tag, friendly_id: id) } }
|
449
|
+
|
450
|
+
subject { create(:post) }
|
451
|
+
|
452
|
+
before do
|
453
|
+
connection.add_column(:tags, :friendly_id, :string)
|
454
|
+
connection.add_column(:posts, :friendly_tag_ids, :string, array: true)
|
455
|
+
post.belongs_to_many(:tags, foreign_key: :friendly_tag_ids, primary_key: :friendly_id)
|
456
|
+
post.reset_column_information
|
457
|
+
tag.reset_column_information
|
458
|
+
end
|
459
|
+
|
460
|
+
after do
|
461
|
+
tag.reset_column_information
|
462
|
+
post.reset_column_information
|
463
|
+
post._reflections.delete(:tags)
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'loads associated records' do
|
467
|
+
subject.update(friendly_tag_ids: tags.pluck(:friendly_id))
|
468
|
+
|
469
|
+
expect(subject.tags.to_sql).to be_eql(<<-SQL.squish)
|
470
|
+
SELECT "tags".* FROM "tags" WHERE "tags"."friendly_id" IN ('a', 'b', 'c')
|
471
|
+
SQL
|
472
|
+
|
473
|
+
expect(subject.tags.load).to be_a(ActiveRecord::Associations::CollectionProxy)
|
474
|
+
expect(subject.tags.to_a).to be_eql(tags)
|
475
|
+
end
|
476
|
+
|
477
|
+
it 'can properly assign tags' do
|
478
|
+
expect(subject.friendly_tag_ids).to be_blank
|
479
|
+
|
480
|
+
subject.tags = tags
|
481
|
+
expect(subject.friendly_tag_ids).to be_eql(%w[a b c])
|
482
|
+
end
|
483
|
+
end
|
443
484
|
end
|
@@ -40,7 +40,7 @@ RSpec.describe 'DistinctOn' do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'raises with invalid relation' do
|
43
|
-
expect { subject.distinct_on(
|
43
|
+
expect { subject.distinct_on(supervisors: :name).to_sql }.to \
|
44
44
|
raise_error(ArgumentError, /Relation for/)
|
45
45
|
end
|
46
46
|
|
data/spec/tests/has_many_spec.rb
CHANGED
@@ -201,6 +201,47 @@ RSpec.describe 'HasMany' do
|
|
201
201
|
expect(query.to_sql).to match(/INNER JOIN "texts"/)
|
202
202
|
expect { query.load }.not_to raise_error
|
203
203
|
end
|
204
|
+
|
205
|
+
context 'with query constraint' do
|
206
|
+
let(:activity) { Activity.create! }
|
207
|
+
|
208
|
+
before do
|
209
|
+
skip('Only Rails 7.1 onwards') unless Post.respond_to?(:query_constraints)
|
210
|
+
|
211
|
+
Post.query_constraints :author_id, :id
|
212
|
+
Activity.query_constraints :author_id, :id
|
213
|
+
Activity.has_many :posts
|
214
|
+
end
|
215
|
+
|
216
|
+
after do
|
217
|
+
Post.instance_variable_set(:@has_query_constraints, false)
|
218
|
+
Post.instance_variable_set(:@query_constraints_list, nil)
|
219
|
+
Post.instance_variable_set(:@_query_constraints_list, nil)
|
220
|
+
Activity.instance_variable_set(:@has_query_constraints, false)
|
221
|
+
Activity.instance_variable_set(:@query_constraints_list, nil)
|
222
|
+
Activity.instance_variable_set(:@_query_constraints_list, nil)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'properly preload records' do
|
226
|
+
FactoryBot.create_list(:post, 5, activity: activity)
|
227
|
+
entries = Activity.all.includes(:posts).load
|
228
|
+
|
229
|
+
expect(entries.size).to be_eql(1)
|
230
|
+
expect(entries.first.posts).to be_loaded
|
231
|
+
expect(entries.first.posts.size).to be_eql(5)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'properly preload records using preloader' do
|
235
|
+
FactoryBot.create_list(:post, 5, activity: activity)
|
236
|
+
entries = ActiveRecord::Associations::Preloader.new(
|
237
|
+
records: Activity.all,
|
238
|
+
associations: [:posts],
|
239
|
+
).call.first.records_by_owner
|
240
|
+
|
241
|
+
expect(entries.size).to be_eql(1)
|
242
|
+
expect(entries.values.first.size).to be_eql(5)
|
243
|
+
end
|
244
|
+
end
|
204
245
|
end
|
205
246
|
|
206
247
|
context 'on array' do
|
data/spec/tests/relation_spec.rb
CHANGED
@@ -125,6 +125,7 @@ RSpec.describe 'TableInheritance' do
|
|
125
125
|
subject.instance_variable_set(:@inheritance_loaded, true)
|
126
126
|
subject.instance_variable_set(:@inheritance_dependencies, scenario)
|
127
127
|
subject.instance_variable_set(:@inheritance_associations, subject.send(:generate_associations))
|
128
|
+
subject.instance_variable_set(:@data_sources_model_names, {})
|
128
129
|
expect(subject.instance_variable_get(:@inheritance_associations)).to eql({
|
129
130
|
'A' => %w(B D C N M),
|
130
131
|
'B' => %w(C N M),
|
@@ -145,9 +146,9 @@ RSpec.describe 'TableInheritance' do
|
|
145
146
|
end
|
146
147
|
|
147
148
|
it 'respect irregular names' do
|
148
|
-
Torque::PostgreSQL.config.irregular_models
|
149
|
+
allow(Torque::PostgreSQL.config).to receive(:irregular_models).and_return({
|
149
150
|
'public.posts' => 'ActivityPost',
|
150
|
-
}
|
151
|
+
})
|
151
152
|
|
152
153
|
subject.send(:prepare_data_sources, *prepare_arguments)
|
153
154
|
list = subject.instance_variable_get(:@data_sources_model_names)
|
@@ -156,15 +157,24 @@ RSpec.describe 'TableInheritance' do
|
|
156
157
|
end
|
157
158
|
|
158
159
|
it 'does not load irregular where the data source is not defined' do
|
159
|
-
Torque::PostgreSQL.config.irregular_models
|
160
|
+
allow(Torque::PostgreSQL.config).to receive(:irregular_models).and_return({
|
160
161
|
'products' => 'Product',
|
161
|
-
}
|
162
|
+
})
|
162
163
|
|
163
164
|
subject.send(:prepare_data_sources, *prepare_arguments)
|
164
165
|
list = subject.instance_variable_get(:@data_sources_model_names)
|
165
166
|
expect(list).to_not have_key('products')
|
166
167
|
end
|
167
168
|
|
169
|
+
it 'works with eager loading' do
|
170
|
+
allow(Torque::PostgreSQL.config).to receive(:eager_load).and_return(true)
|
171
|
+
ActivityPost.reset_table_name
|
172
|
+
|
173
|
+
list = subject.instance_variable_get(:@data_sources_model_names)
|
174
|
+
expect(list).to have_key('activity_posts')
|
175
|
+
expect(list['activity_posts']).to eql(ActivityPost)
|
176
|
+
end
|
177
|
+
|
168
178
|
{
|
169
179
|
'activities' => 'Activity',
|
170
180
|
'activity_posts' => 'ActivityPost',
|
@@ -237,7 +247,7 @@ RSpec.describe 'TableInheritance' do
|
|
237
247
|
expect(other.table_name).to eql('authors')
|
238
248
|
end
|
239
249
|
|
240
|
-
it 'respects the table name prefix and
|
250
|
+
it 'respects the table name prefix and suffix defined on parent module' do
|
241
251
|
mod = Object.const_set('Private', Module.new)
|
242
252
|
mod.define_singleton_method(:table_name_prefix) { 'private.' }
|
243
253
|
mod.define_singleton_method(:table_name_suffix) { '_bundle' }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: torque-postgresql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -289,6 +289,7 @@ licenses:
|
|
289
289
|
metadata:
|
290
290
|
source_code_uri: https://github.com/crashtech/torque-postgresql
|
291
291
|
bug_tracker_uri: https://github.com/crashtech/torque-postgresql/issues
|
292
|
+
changelog_uri: https://github.com/crashtech/torque-postgresql/releases
|
292
293
|
post_install_message:
|
293
294
|
rdoc_options:
|
294
295
|
- "--title"
|