Skip to content

Commit

Permalink
activerecord: Support insert_all on relation (for Rails 7.2) (#661)
Browse files Browse the repository at this point in the history
ActiveRecord supports insert and upsert methods on relation classes
(AssociationRelation and CollectionProxy) since v6.1.

The implementation of insert_all has been changed since v7.2. The
implementation was moved to AR::Relation from AR::Persistence.  So types
follow the new structure.

refs:

* #658
* rails/rails#38899
* rails/rails#51805
* https://github.com/rails/rails/blob/v6.1.7.8/activerecord/CHANGELOG.md
  • Loading branch information
tk0miya authored Sep 13, 2024
1 parent 2275d26 commit e193a14
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
12 changes: 12 additions & 0 deletions gems/activerecord/7.2/_test/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class ApplicationRecord < ActiveRecord::Base
end

class User < ApplicationRecord
# @dynamic articles
has_many :articles

enum status: { active: 0, inactive: 1 }, _suffix: true
enum :role, { admin: 0, user: 1 }, _prefix: true
enum :classify, %w[hoge fuga], _default: "hoge"
Expand All @@ -24,6 +27,9 @@ class User < ApplicationRecord
}
end

class Article < ApplicationRecord
end

User.where.missing.to_sql
User.deterministic_encrypted_attributes
User.source_attribute_from_preserved_attribute(:phrase)
Expand All @@ -38,6 +44,12 @@ class User < ApplicationRecord
user.encrypted_attribute?(:secret)
user.decrypt
user.ciphertext_for(:token)
user.articles.insert({ id: 1, name: 'James' }, returning: %i[id name], unique_by: :id, record_timestamps: true)
user.articles.insert!({ id: 1, name: 'James' }, returning: %i[id name], record_timestamps: true)
user.articles.insert_all([{ id: 1, name: 'James' }], returning: %i[id name], unique_by: :id, record_timestamps: true)
user.articles.insert_all!([{ id: 1, name: 'James' }], returning: %i[id name], record_timestamps: true)
user.articles.upsert({ id: 1, name: 'James' }, returning: %i[id name], unique_by: :id, record_timestamps: true)
user.articles.upsert_all([{ id: 1, name: 'James' }], returning: %i[id name], unique_by: :id, record_timestamps: true)

user = User.new
user.normalize_attribute(:email)
Expand Down
13 changes: 13 additions & 0 deletions gems/activerecord/7.2/_test/test.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,18 @@ module Test

class ActiveRecord_Relation < ::ActiveRecord::Relation
end

def articles: () -> Article::ActiveRecord_Associations_CollectionProxy
end

class Article < ApplicationRecord
extend ::ActiveRecord::Base::ClassMethods[Article, ActiveRecord_Relation, Integer]

class ActiveRecord_Relation < ::ActiveRecord::Relation
end

class ActiveRecord_Associations_CollectionProxy < ::ActiveRecord::Associations::CollectionProxy
include ::ActiveRecord::Relation::Methods[Article, Integer]
end
end
end
27 changes: 16 additions & 11 deletions gems/activerecord/7.2/activerecord-7.2.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ module ActiveRecord
extend Normalization::ClassMethods
end

class Relation
def insert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert_all!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def upsert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def upsert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
end

class Relation
module QueryMethods
def with_recursive: (*untyped) -> untyped
Expand Down Expand Up @@ -95,22 +104,18 @@ module ActiveRecord
?connection_pool: ConnectionAdapters::ConnectionPool?) -> void
end

module Persistence
extend ActiveSupport::Concern

module ClassMethods
def insert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
module Querying
def insert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped

def insert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped

def insert!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped

def insert_all!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def insert_all!: (untyped attributes, ?returning: untyped?, ?record_timestamps: bool?) -> untyped

def upsert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
def upsert: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped

def upsert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
end
def upsert_all: (untyped attributes, ?unique_by: untyped?, ?returning: untyped?, ?record_timestamps: bool?) -> untyped
end

module Querying
Expand Down

0 comments on commit e193a14

Please sign in to comment.