-
Notifications
You must be signed in to change notification settings - Fork 108
Open
Description
Affected versions / refs
- Gem: activerecord-multi-tenant
- Commit tested for Rails 7.2 support: 0ac43aa
- Rails 8 work is also affected (see Support rails 8.0.0)
- Note: latest release (2.4.0) still declares support only up to Rails 7.0, so people may be pinning to these commits.
Summary
When calling relation.update_all with an assignment that uses Arel.sql(column_name) to reference another column, it works correctly outside a tenant block.
Inside MultiTenant.with(...), the Arel.sql value is coerced to a literal (e.g. 1 for booleans), so every row gets the same constant instead of the column value.
Expected behavior
Arel.sql("active") should be treated as a SQL expression and compiled as:
UPDATE "users" SET "user_valid" = "users"."active", "active" = ? [["active", 0]]
WHERE "users"."practice_id" = 1;
Actual behavior
Within MultiTenant.with, the assignment is type-cast/quoted as a literal:
UPDATE "users"
SET "user_valid" = 1, "active" = 0
WHERE "users"."id" IN (
SELECT "users"."id" FROM "users" WHERE "users"."practice_id" = 1
) AND "users"."practice_id" = 1;
Reproduction
Schema
# users: id, practice_id:bigint, user_valid:boolean, active:boolean, timestamps
class User < ApplicationRecord
multi_tenant :practice
end
Repo script:
users = User.all
# Baseline: OUTSIDE tenant
users.update_all(user_valid: Arel.sql("active"), active: false)
# => UPDATE "users" SET "user_valid" = (active), "active" = 0
practice = Practice.first
MultiTenant.with(practice) do
users = User.all
users.update_all(user_valid: Arel.sql("active"), active: false)
end
# => UPDATE "users" SET "user_valid" = 1, "active" = 0 ...
Why this likely happens
Active Record normally treats Arel::Nodes::SqlLiteral as “don’t quote/type-cast this.”
Inside the gem’s tenant scoping path, update_all seems to flow through a code path that type-casts the update hash, converting the Arel.sql(...) node into a bound literal.
Environment
- Rails: 7.2.x (also visible with Rails 8 prerelease)
- DB: PostgreSQL (likely adapter-agnostic)
- activerecord-multi-tenant: GitHub ref 0ac43aa
Metadata
Metadata
Assignees
Labels
No labels