Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reset sequence_name after tenant switch #51

Merged
merged 1 commit into from
May 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/apartment/adapters/postgresql_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def initialize(config)
def reset
@current = default_tenant
Apartment.connection.schema_search_path = full_search_path
reset_sequence_names
end

def init
Expand Down Expand Up @@ -78,6 +79,7 @@ def connect_to_new(tenant = nil)
# there is a issue for prepared statement with changing search_path.
# https://www.postgresql.org/docs/9.3/static/sql-prepare.html
Apartment.connection.clear_cache! if postgresql_version < 90_300
reset_sequence_names
rescue *rescuable_exceptions
raise TenantNotFound, "One of the following schema(s) is invalid: \"#{tenant}\" #{full_search_path}"
end
Expand Down Expand Up @@ -109,6 +111,19 @@ def postgresql_version
# public from Rails 5.0.
Apartment.connection.send(:postgresql_version)
end

def reset_sequence_names
# sequence_name contains the schema, so it must be reset after switch
# There is `reset_sequence_name`, but that method actually goes to the database
# to find out the new name. Therefore, we do this hack to only unset the name,
# and it will be dynamically found the next time it is needed
ActiveRecord::Base.descendants
.select { |c| c.instance_variable_defined?(:@sequence_name) }
.reject { |c| c.instance_variable_defined?(:@explicit_sequence_name) && c.instance_variable_get(:@explicit_sequence_name) }
.each do |c|
c.remove_instance_variable :@sequence_name
end
end
end

# Another Adapter for Postgresql when using schemas and SQL
Expand Down
2 changes: 2 additions & 0 deletions spec/examples/schema_adapter_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,11 @@
it 'connects and resets' do
subject.switch(schema1) do
expect(connection.schema_search_path).to start_with %("#{schema1}")
expect(User.sequence_name).to eq "#{schema1}.#{User.table_name}_id_seq"
end

expect(connection.schema_search_path).to start_with %("#{public_schema}")
expect(User.sequence_name).to eq "#{public_schema}.#{User.table_name}_id_seq"
end
end

Expand Down