Skip to content

Commit

Permalink
Fix for belongs_to_many association with custom keys
Browse files Browse the repository at this point in the history
  • Loading branch information
crashtech committed Mar 13, 2024
1 parent 7d971b0 commit ad9aa36
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/torque/postgresql/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Torque
module PostgreSQL
VERSION = '3.3.1'
VERSION = '3.3.2'
end
end
18 changes: 9 additions & 9 deletions spec/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -77,22 +77,22 @@
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
end

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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down
43 changes: 42 additions & 1 deletion spec/tests/belongs_to_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion spec/tests/distinct_on_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion spec/tests/relation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit ad9aa36

Please sign in to comment.