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

Support rails 7.2 #239

Merged
merged 7 commits into from
Aug 23, 2024
Merged

Conversation

alpaca-tc
Copy link
Contributor

@alpaca-tc alpaca-tc commented May 30, 2024

The pull request is currently in draft status.
Once the beta release of Rails is replaced by a stable release, I will open the pull request.

Rails 7.2.0 has been released, I have added support for activerecord-multitenant.
The changes were commented on in the review.

@alpaca-tc alpaca-tc force-pushed the support-rails-7-2 branch 3 times, most recently from c593a5b to c0707d1 Compare August 14, 2024 00:50
@@ -12,7 +12,7 @@ def has_and_belongs_to_many_with_tenant(name, scope = nil, **options, &extension
# rubocop:enable Naming/PredicateName
has_and_belongs_to_many_without_tenant(name, scope, **options, &extension)

middle_reflection = _reflections[name.to_s].through_reflection
middle_reflection = _reflect_on_association(name.to_s).through_reflection
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rails 7.2, the keys of _reflections was changed from String to Symbol.
I used _reflect_on_association to work without type conversion.

def cached_find_by_statement(key, &block)
return super unless respond_to?(:scoped_by_tenant?) && scoped_by_tenant?
if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 2
def cached_find_by_statement(connection, key, &block)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Rails 7.2, connection was added as the first argument.

Comment on lines +42 to +43
elsif ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 2
build_arel(klass.connection)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Rails 7.2, connection was added as the first argument.

Comment on lines +136 to +143
# related: https://github.com/rails/rails/pull/49765
around do |example|
prev = Account.attributes_for_inspect
Account.attributes_for_inspect = :all
example.run
ensure
Account.attributes_for_inspect = prev
end
Copy link
Contributor Author

@alpaca-tc alpaca-tc Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Rails 7.2, #inspect doesn't print all attributes. This around hook will output all attributes for compatibility.

related: rails/rails#49765

elsif table_name &&
connection.schema_cache.columns_hash(table_name).include?(DEFAULT_ID_FIELD)
DEFAULT_ID_FIELD
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To maintain compatibility with existing behavior, pk returns a single value rather than an array. However, the default Rails 7.2 is working on composite primary key support, which will return an array.
I think it is worth considering to what extent this gem will be left to the behavior of Rails itself in the future, and to what extent the gem will be extended.

@@ -42,20 +42,15 @@ def partition_key
.try(:instance_variable_get, :@partition_key)
end

# Avoid primary_key errors when using composite primary keys (e.g. id, tenant_id)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In supporting multiple versions, the variable states and values have become more complex.
I tried to override the #reset_primary_key private method that is called when initializing @primary_key so that it can use the same logic for each version.

Please review as it may have side effects compared to other changes.

@alpaca-tc alpaca-tc marked this pull request as ready for review August 14, 2024 01:13
@alpaca-tc
Copy link
Contributor Author

@serprex Rails 7.2 has been released and PR is now open. Please review 😄 🙏

Copy link
Collaborator

@serprex serprex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, note however that it's almost been a year now since I left MS for PeerDB

related: rails/rails#51726

`_reflect_on_association` is also a private API and will may be broken, but it works
for both String and Symbol, absorbing type differences, so use this one.
By default, only `id` is output, so set `:all` to output all attributes for testing.
related: rails/rails#49765
ar-multitenant expects that #primary_key returns single column instead of composite primary_keys for backward compatibilities.

Previously overwriting #primary_key to return single pk, but since the timing for
writing @primary_key has changed since Rails 7.2, this way is no longer available.
Instead, overwriting `#reset_primary_key`, which handles calculating `@primary_key`.
@gurkanindibay
Copy link
Contributor

@alpaca-tc static-checks are failing

Comment on lines 382 to 390
key = Array.wrap(key) + [MultiTenant.current_tenant_id.to_s]
super(connection, key, &block)
end
else
def cached_find_by_statement(key, &block)
return super unless respond_to?(:scoped_by_tenant?) && scoped_by_tenant?

key = Array.wrap(key) + [MultiTenant.current_tenant_id.to_s]
super(key, &block)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
key = Array.wrap(key) + [MultiTenant.current_tenant_id.to_s]
super(connection, key, &block)
end
else
def cached_find_by_statement(key, &block)
return super unless respond_to?(:scoped_by_tenant?) && scoped_by_tenant?
key = Array.wrap(key) + [MultiTenant.current_tenant_id.to_s]
super(key, &block)
super(connection, Array.wrap(key) + [MultiTenant.current_tenant_id.to_s], &block)
end
else
def cached_find_by_statement(key, &block)
return super unless respond_to?(:scoped_by_tenant?) && scoped_by_tenant?
super(Array.wrap(key) + [MultiTenant.current_tenant_id.to_s], &block)

not sure if super with implicit args picks up on key being rebound, maybe inlining expression gets past static check

@alpaca-tc
Copy link
Contributor Author

@gurkanindibay fixed 💛

@gurkanindibay gurkanindibay merged commit 0ac43aa into citusdata:master Aug 23, 2024
123 checks passed
@gurkanindibay
Copy link
Contributor

@alpaca-tc thanks for your contribution

@alpaca-tc alpaca-tc deleted the support-rails-7-2 branch August 28, 2024 01:56
@yonda
Copy link

yonda commented Sep 2, 2024

@gurkanindibay @alpaca-tc

Thank you for addressing this issue. This fix is crucial for users who have upgraded to Rails 7.2, as the current version throws an ArgumentError with the find_by method.

Is there an estimated timeline for when we might see a new release that includes this change? Many of us are eagerly waiting for this fix to be available in a stable release.

Thanks again for your work on this valuable gem!

kimihito added a commit to kimihito/activerecord-multi-tenant that referenced this pull request Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants