Skip to content
代码片段 群组 项目
未验证 提交 a8dfd13d 编辑于 作者: Thong Kuah's avatar Thong Kuah 提交者: GitLab
浏览文件

Merge branch 'mmj-ar-patch' into 'master'

Add patch for `find_or_create_by`/`find_or_create_by!`

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144457



Merged-by: default avatarThong Kuah <tkuah@gitlab.com>
Approved-by: default avatarThong Kuah <tkuah@gitlab.com>
Reviewed-by: default avatarThong Kuah <tkuah@gitlab.com>
Co-authored-by: default avatarManoj M J <mmj@gitlab.com>
No related branches found
No related tags found
无相关合并请求
......@@ -3,6 +3,7 @@
require "active_record"
require_relative "gitlab_patches/version"
require_relative "gitlab_patches/rescue_from"
require_relative "gitlab_patches/relation/find_or_create_by"
require_relative "gitlab_patches/partitioning"
module ActiveRecord
......
# frozen_string_literal: true
module ActiveRecord
module GitlabPatches
module Relation
module FindOrCreateBy
# Adds patch for ActiveRecord `find_or_create_by`/`find_or_create_by!` methods
# so as to prevent it from opening subtransactions.
# Rails commit: https://github.com/rails/rails/commit/023a3eb3c046091a5d52027393a6d29d0576da01
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/439567
def find_or_create_by(attributes, &block)
find_by(attributes) || create(attributes, &block)
end
def find_or_create_by!(attributes, &block)
find_by(attributes) || create!(attributes, &block)
end
end
end
end
end
ActiveSupport.on_load(:active_record) do
ActiveRecord::Relation.prepend(ActiveRecord::GitlabPatches::Relation::FindOrCreateBy)
end
# frozen_string_literal: true
RSpec.describe ActiveRecord::GitlabPatches::Relation::FindOrCreateBy do
let(:model) do
Class.new(Project) do
validates :name, presence: true
def self.name
"Project"
end
end
end
describe '#find_or_create_by' do
it 'does not trigger a subtransaction' do
expect(model.find_by(id: 99990, name: 'project')).to be_nil
expect(model.connection).not_to receive(:transaction).with(requires_new: true)
project = model.find_or_create_by(id: 99990, name: 'project')
expect(project).to be_present
end
it 'finds or creates the record' do
expect(model.find_by(id: 99991, name: 'project')).to be_nil
project = model.find_or_create_by(id: 99991, name: 'project')
expect(project).to be_present
expect(project).to eq(model.find_or_create_by(id: 99991, name: 'project'))
end
it 'does not raise error if validations are not met' do
expect { model.find_or_create_by(id: 99992) }.not_to raise_error
end
end
describe '#find_or_create_by!' do
it 'does not trigger a subtransaction' do
expect(model.find_by(id: 99993, name: 'project')).to be_nil
expect(model.connection).not_to receive(:transaction).with(requires_new: true)
project = model.find_or_create_by!(id: 99993, name: 'project')
expect(project).to be_present
end
it 'finds or creates the record' do
expect(model.find_by(id: 99994, name: 'project')).to be_nil
project = model.find_or_create_by!(id: 99994, name: 'project')
expect(project).to be_present
expect(project).to eq(model.find_or_create_by!(id: 99994, name: 'project'))
end
it 'raises error if validations are not met' do
expect { model.find_or_create_by!(id: 99995) }.to raise_error(ActiveRecord::RecordInvalid)
end
end
end
......@@ -6,7 +6,9 @@
ActiveRecord::Base.logger = Logger.new('/dev/null')
ActiveRecord::Schema.define do
create_table :projects, force: true
create_table :projects, force: true do |t|
t.string :name
end
create_table :pipelines, force: true do |t|
t.integer :project_id
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册