From 80250d8674ffbe7b8a8f86913b736efe65739f6b Mon Sep 17 00:00:00 2001 From: Markos Fragkakis Date: Wed, 17 Apr 2024 12:12:24 +0300 Subject: [PATCH 1/2] Updated .gitignore to ignore .idea and .byebug_history files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index d2b2f0d2..299ae76c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,16 @@ tmtags ## VIM *.swp +## Idea +.idea + ## PROJECT::GENERAL coverage rdoc pkg *.gem *.lock +.byebug_history ## PROJECT::SPECIFIC log/*.log From c0f1cc3e3d70456de37fbb34c677e1b571c7041b Mon Sep 17 00:00:00 2001 From: Markos Fragkakis Date: Wed, 17 Apr 2024 12:25:14 +0300 Subject: [PATCH 2/2] Adding support for Rails 7.1 composite PKs --- lib/activerecord-import/import.rb | 7 ++-- test/models/author.rb | 7 ++++ test/models/book.rb | 7 ++-- test/models/composite_book.rb | 19 +++++++++++ test/models/composite_chapter.rb | 9 +++++ test/models/customer.rb | 16 ++++++--- test/models/order.rb | 15 +++++--- test/models/tag.rb | 7 +++- test/models/tag_alias.rb | 6 +++- test/schema/postgresql_schema.rb | 34 +++++++++++++++++++ test/support/postgresql/import_examples.rb | 12 +++++++ .../shared_examples/recursive_import.rb | 18 ++++++++++ test/test_helper.rb | 4 ++- 13 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 test/models/author.rb create mode 100644 test/models/composite_book.rb create mode 100644 test/models/composite_chapter.rb diff --git a/lib/activerecord-import/import.rb b/lib/activerecord-import/import.rb index 50f9d7a2..e772a52f 100644 --- a/lib/activerecord-import/import.rb +++ b/lib/activerecord-import/import.rb @@ -941,7 +941,7 @@ def load_association_ids(model) association = association.target next if association.blank? || model.public_send(column_name).present? - association_primary_key = Array(association_reflection.association_primary_key)[column_index] + association_primary_key = Array(association_reflection.association_primary_key.tr("[]:", "").split(", "))[column_index] model.public_send("#{column_name}=", association.send(association_primary_key)) end end @@ -996,7 +996,10 @@ def find_associated_objects_for_import(associated_objects_by_class, model) changed_objects = association.select { |a| a.new_record? || a.changed? } changed_objects.each do |child| - child.public_send("#{association_reflection.foreign_key}=", model.id) + Array(association_reflection.inverse_of&.foreign_key || association_reflection.foreign_key).each_with_index do |column, index| + child.public_send("#{column}=", Array(model.id)[index]) + end + # For polymorphic associations association_name = if model.class.respond_to?(:polymorphic_name) model.class.polymorphic_name diff --git a/test/models/author.rb b/test/models/author.rb new file mode 100644 index 00000000..f4c0446d --- /dev/null +++ b/test/models/author.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Author < ActiveRecord::Base + if ENV['AR_VERSION'].to_f >= 7.1 + has_many :composite_books, query_constraints: [:id, :author_id], inverse_of: :author + end +end diff --git a/test/models/book.rb b/test/models/book.rb index 7beee340..1fdc8cda 100644 --- a/test/models/book.rb +++ b/test/models/book.rb @@ -2,8 +2,11 @@ class Book < ActiveRecord::Base belongs_to :topic, inverse_of: :books - belongs_to :tag, foreign_key: [:tag_id, :parent_id] unless ENV["SKIP_COMPOSITE_PK"] - + if ENV['AR_VERSION'].to_f <= 7.0 + belongs_to :tag, foreign_key: [:tag_id, :parent_id] unless ENV["SKIP_COMPOSITE_PK"] + else + belongs_to :tag, query_constraints: [:tag_id, :parent_id] unless ENV["SKIP_COMPOSITE_PK"] + end has_many :chapters, inverse_of: :book has_many :discounts, as: :discountable has_many :end_notes, inverse_of: :book diff --git a/test/models/composite_book.rb b/test/models/composite_book.rb new file mode 100644 index 00000000..c269ed12 --- /dev/null +++ b/test/models/composite_book.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class CompositeBook < ActiveRecord::Base + self.primary_key = %i[id author_id] + belongs_to :author + if ENV['AR_VERSION'].to_f <= 7.0 + unless ENV["SKIP_COMPOSITE_PK"] + has_many :composite_chapters, inverse_of: :composite_book, + foreign_key: [:id, :author_id] + end + else + has_many :composite_chapters, inverse_of: :composite_book, + query_constraints: [:id, :author_id] + end + + def self.sequence_name + "composite_book_id_seq" + end +end diff --git a/test/models/composite_chapter.rb b/test/models/composite_chapter.rb new file mode 100644 index 00000000..9b9d66df --- /dev/null +++ b/test/models/composite_chapter.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class CompositeChapter < ActiveRecord::Base + if ENV['AR_VERSION'].to_f >= 7.1 + belongs_to :composite_book, inverse_of: :composite_chapters, + query_constraints: [:composite_book_id, :author_id] + end + validates :title, presence: true +end diff --git a/test/models/customer.rb b/test/models/customer.rb index 9686bd83..b8312cd8 100644 --- a/test/models/customer.rb +++ b/test/models/customer.rb @@ -2,9 +2,17 @@ class Customer < ActiveRecord::Base unless ENV["SKIP_COMPOSITE_PK"] - has_many :orders, - inverse_of: :customer, - primary_key: %i(account_id id), - foreign_key: %i(account_id customer_id) + if ENV['AR_VERSION'].to_f <= 7.0 + has_many :orders, + inverse_of: :customer, + primary_key: %i(account_id id), + foreign_key: %i(account_id customer_id) + else + has_many :orders, + inverse_of: :customer, + primary_key: %i(account_id id), + query_constraints: %i(account_id customer_id) + end + end end diff --git a/test/models/order.rb b/test/models/order.rb index 45a67fcf..e29e6a9b 100644 --- a/test/models/order.rb +++ b/test/models/order.rb @@ -2,9 +2,16 @@ class Order < ActiveRecord::Base unless ENV["SKIP_COMPOSITE_PK"] - belongs_to :customer, - inverse_of: :orders, - primary_key: %i(account_id id), - foreign_key: %i(account_id customer_id) + if ENV['AR_VERSION'].to_f <= 7.0 + belongs_to :customer, + inverse_of: :orders, + primary_key: %i(account_id id), + foreign_key: %i(account_id customer_id) + else + belongs_to :customer, + inverse_of: :orders, + primary_key: %i(account_id id), + query_constraints: %i(account_id customer_id) + end end end diff --git a/test/models/tag.rb b/test/models/tag.rb index e062b3b4..dede825a 100644 --- a/test/models/tag.rb +++ b/test/models/tag.rb @@ -1,7 +1,12 @@ # frozen_string_literal: true class Tag < ActiveRecord::Base - self.primary_keys = :tag_id, :publisher_id unless ENV["SKIP_COMPOSITE_PK"] + if ENV['AR_VERSION'].to_f <= 7.0 + self.primary_keys = :tag_id, :publisher_id unless ENV["SKIP_COMPOSITE_PK"] + else + self.primary_key = [:tag_id, :publisher_id] unless ENV["SKIP_COMPOSITE_PK"] + end + self.primary_key = [:tag_id, :publisher_id] unless ENV["SKIP_COMPOSITE_PK"] has_many :books, inverse_of: :tag has_many :tag_aliases, inverse_of: :tag end diff --git a/test/models/tag_alias.rb b/test/models/tag_alias.rb index 2beeb21a..d9636793 100644 --- a/test/models/tag_alias.rb +++ b/test/models/tag_alias.rb @@ -2,6 +2,10 @@ class TagAlias < ActiveRecord::Base unless ENV["SKIP_COMPOSITE_PK"] - belongs_to :tag, foreign_key: [:tag_id, :parent_id], required: true + if ENV['AR_VERSION'].to_f <= 7.0 + belongs_to :tag, foreign_key: [:tag_id, :parent_id], required: true + else + belongs_to :tag, query_constraints: [:tag_id, :parent_id], required: true + end end end diff --git a/test/schema/postgresql_schema.rb b/test/schema/postgresql_schema.rb index e05288fa..b5dcb5a4 100644 --- a/test/schema/postgresql_schema.rb +++ b/test/schema/postgresql_schema.rb @@ -57,4 +57,38 @@ end add_index :alarms, [:device_id, :alarm_type], unique: true, where: 'status <> 0' + + unless ENV["SKIP_COMPOSITE_PK"] + create_table :authors, force: :cascade do |t| + t.string :name + end + + execute %( + DROP SEQUENCE IF EXISTS composite_book_id_seq CASCADE; + CREATE SEQUENCE composite_book_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + DROP TABLE IF EXISTS composite_books; + CREATE TABLE composite_books ( + id bigint DEFAULT nextval('composite_book_id_seq'::regclass) NOT NULL, + title character varying, + author_id bigint + ); + + ALTER TABLE ONLY composite_books ADD CONSTRAINT fk_rails_040a418131 FOREIGN KEY (author_id) REFERENCES authors(id); + ).split.join(' ').strip + end + + create_table :composite_chapters, force: :cascade do |t| + t.string :title + t.integer :composite_book_id, null: false + t.integer :author_id, null: false + t.datetime :created_at + t.datetime :updated_at + end end diff --git a/test/support/postgresql/import_examples.rb b/test/support/postgresql/import_examples.rb index 111cb0b8..3da146e8 100644 --- a/test/support/postgresql/import_examples.rb +++ b/test/support/postgresql/import_examples.rb @@ -351,6 +351,18 @@ def should_support_postgresql_import_functionality assert_equal db_customer.orders.last, db_order assert_not_equal db_order.customer_id, nil end + + it "should import models with auto-incrementing ID successfully" do + author = Author.create!(name: "Foo Barson") + + books = [] + 2.times do |i| + books << CompositeBook.new(author_id: author.id, title: "book #{i}") + end + assert_difference "CompositeBook.count", +2 do + CompositeBook.import books + end + end end end end diff --git a/test/support/shared_examples/recursive_import.rb b/test/support/shared_examples/recursive_import.rb index 80505774..f248b6d8 100644 --- a/test/support/shared_examples/recursive_import.rb +++ b/test/support/shared_examples/recursive_import.rb @@ -165,6 +165,24 @@ def should_support_recursive_import assert_equal 1, tags[0].tag_id assert_equal 2, tags[1].tag_id end + + if ENV['AR_VERSION'].to_f >= 7.1 + it "should import models with auto-incrementing ID successfully with recursive set to true" do + author = Author.create!(name: "Foo Barson") + books = [] + 2.times do |i| + books << CompositeBook.new(author_id: author.id, title: "Book #{i}", composite_chapters: [ + CompositeChapter.new(title: "Book #{i} composite chapter 1"), + CompositeChapter.new(title: "Book #{i} composite chapter 2"), + ]) + end + assert_difference "CompositeBook.count", +2 do + assert_difference "CompositeChapter.count", +4 do + CompositeBook.import books, recursive: true + end + end + end + end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index d8e761d7..02eb2a1d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -33,7 +33,9 @@ begin require 'composite_primary_keys' rescue LoadError - ENV["SKIP_COMPOSITE_PK"] = "true" + if ENV['AR_VERSION'].to_f <= 7.1 + ENV['SKIP_COMPOSITE_PK'] = 'true' + end end # Support MySQL 5.7