From ad9aa36c706b218ad91b5855d8b77b981db8b236 Mon Sep 17 00:00:00 2001 From: Carlos Silva Date: Wed, 13 Mar 2024 12:43:58 -0300 Subject: [PATCH] Fix for belongs_to_many association with custom keys --- .../belongs_to_many_association.rb | 4 +- lib/torque/postgresql/version.rb | 2 +- spec/schema.rb | 18 ++++---- spec/tests/belongs_to_many_spec.rb | 43 ++++++++++++++++++- spec/tests/distinct_on_spec.rb | 2 +- spec/tests/relation_spec.rb | 2 +- 6 files changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/torque/postgresql/associations/belongs_to_many_association.rb b/lib/torque/postgresql/associations/belongs_to_many_association.rb index 2302880..60318fc 100644 --- a/lib/torque/postgresql/associations/belongs_to_many_association.rb +++ b/lib/torque/postgresql/associations/belongs_to_many_association.rb @@ -12,9 +12,9 @@ class BelongsToManyAssociation < ::ActiveRecord::Associations::CollectionAssocia ## CUSTOM def ids_reader if loaded? - target.pluck(reflection.association_primary_key) + target.pluck(reflection.active_record_primary_key) elsif !target.empty? - load_target.pluck(reflection.association_primary_key) + load_target.pluck(reflection.active_record_primary_key) else stale_state || column_default_value end diff --git a/lib/torque/postgresql/version.rb b/lib/torque/postgresql/version.rb index 010ea64..9a9588d 100644 --- a/lib/torque/postgresql/version.rb +++ b/lib/torque/postgresql/version.rb @@ -2,6 +2,6 @@ module Torque module PostgreSQL - VERSION = '3.3.1' + VERSION = '3.3.2' end end diff --git a/spec/schema.rb b/spec/schema.rb index 1e67981..2b89ef6 100644 --- a/spec/schema.rb +++ b/spec/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -version = 2 +version = 3 return if ActiveRecord::Migrator.current_version == version ActiveRecord::Schema.define(version: version) do @@ -77,14 +77,14 @@ create_table "texts", force: :cascade do |t| t.integer "user_id" t.string "content" - t.enum "conflict", enum_type: :conflicts + t.enum "conflict", enum_type: :conflicts end create_table "comments", force: :cascade do |t| - t.integer "user_id", null: false + t.integer "user_id", null: false t.integer "comment_id" t.integer "video_id" - t.text "content", null: false + t.text "content", null: false t.string "kind" t.index ["user_id"], name: "index_comments_on_user_id", using: :btree t.index ["comment_id"], name: "index_comments_on_comment_id", using: :btree @@ -92,7 +92,7 @@ create_table "courses", force: :cascade do |t| t.integer "category_id" - t.string "title", null: false + t.string "title", null: false t.interval "duration" t.enum "types", enum_type: :types, array: true t.datetime "created_at", null: false @@ -108,7 +108,7 @@ t.integer "activity_id" t.string "title" t.text "content" - t.enum "status", enum_type: :content_status + t.enum "status", enum_type: :content_status t.index ["author_id"], name: "index_posts_on_author_id", using: :btree end @@ -120,8 +120,8 @@ end create_table "users", force: :cascade do |t| - t.string "name", null: false - t.enum "role", enum_type: :roles, default: :visitor + t.string "name", null: false + t.enum "role", enum_type: :roles, default: :visitor t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -137,7 +137,7 @@ t.integer "author_id" t.string "title" t.boolean "active" - t.enum "kind", enum_type: :types + t.enum "kind", enum_type: :types t.datetime "created_at", null: false t.datetime "updated_at", null: false end diff --git a/spec/tests/belongs_to_many_spec.rb b/spec/tests/belongs_to_many_spec.rb index a2ab552..ce81850 100644 --- a/spec/tests/belongs_to_many_spec.rb +++ b/spec/tests/belongs_to_many_spec.rb @@ -400,7 +400,7 @@ let(:player) { Class.new(ActiveRecord::Base) } let(:other) { player.create } - # TODO: Set as a shred example + # TODO: Set as a shared example before do connection.create_table(:players, id: :uuid) { |t| t.string :name } connection.create_table(:games, id: :uuid) { |t| t.uuid :player_ids, array: true } @@ -440,4 +440,45 @@ expect { query.load }.not_to raise_error end end + + context 'using custom keys' do + let(:connection) { ActiveRecord::Base.connection } + let(:post) { Post } + let(:tag) { Tag } + let(:tags) { %w[a b c].map { |id| create(:tag, friendly_id: id) } } + + subject { create(:post) } + + before do + connection.add_column(:tags, :friendly_id, :string) + connection.add_column(:posts, :friendly_tag_ids, :string, array: true) + post.belongs_to_many(:tags, foreign_key: :friendly_tag_ids, primary_key: :friendly_id) + post.reset_column_information + tag.reset_column_information + end + + after do + tag.reset_column_information + post.reset_column_information + post._reflections.delete(:tags) + end + + it 'loads associated records' do + subject.update(friendly_tag_ids: tags.pluck(:friendly_id)) + + expect(subject.tags.to_sql).to be_eql(<<-SQL.squish) + SELECT "tags".* FROM "tags" WHERE "tags"."friendly_id" IN ('a', 'b', 'c') + SQL + + expect(subject.tags.load).to be_a(ActiveRecord::Associations::CollectionProxy) + expect(subject.tags.to_a).to be_eql(tags) + end + + it 'can properly assign tags' do + expect(subject.friendly_tag_ids).to be_blank + + subject.tags = tags + expect(subject.friendly_tag_ids).to be_eql(%w[a b c]) + end + end end diff --git a/spec/tests/distinct_on_spec.rb b/spec/tests/distinct_on_spec.rb index b55eed2..7300606 100644 --- a/spec/tests/distinct_on_spec.rb +++ b/spec/tests/distinct_on_spec.rb @@ -40,7 +40,7 @@ end it 'raises with invalid relation' do - expect { subject.distinct_on(tags: :name).to_sql }.to \ + expect { subject.distinct_on(supervisors: :name).to_sql }.to \ raise_error(ArgumentError, /Relation for/) end diff --git a/spec/tests/relation_spec.rb b/spec/tests/relation_spec.rb index 9a99b55..a4c803a 100644 --- a/spec/tests/relation_spec.rb +++ b/spec/tests/relation_spec.rb @@ -44,7 +44,7 @@ def attribute(relation, name) end it 'raises on relation not present' do - check = [tags: :name] + check = [supervisors: :name] expect{ subject.call(check) }.to raise_error(ArgumentError, /Relation for/) end