Rails 在分片中加入了错误的表
Rails joins wrong tables in shards
我有以下数据库结构,模式克隆到 2 个数据库:
users
(身份证,姓名)
todos
(id, title)
todos_users
(user_id, todo_id)
我的软件有 2 个不同的客户,大公司和小公司。分片代表公司自己的待办事项,不想分开。所有用户,包括小公司用户都存储在大公司数据库中。这是因为我们没有单独登录,有些用户可以同时使用大公司和小公司的待办事项列表。
我们在使用这些模型时遇到了以下问题:
# ApplicationRecord connects to the current shard the user is logged to
# GlobalRecord always uses the Big company -database
class User < GlobalRecord
end
class Todo < ApplicationRecord
has_and_belongs_to_many :users
end
结果查询例如 DatabaseProxy.on_shard(shard: :small_company) do Todo.first.users end
SELECT "todos".* FROM "todos" ORDER BY "todos"."id" ASC LIMIT [["LIMIT", 1]]
SELECT "users".* FROM "users" INNER JOIN "todos_users" ON "users"."id" = "todos_users"."user_id" WHERE "todos_users"."todo_id" =
问题来了;它在主分片中加入 todos_users
到 users
!这是有问题的,因为待办事项不在大公司数据库中,而是在小公司数据库中。因此,我插入小型公司数据库 todos_users
的所有信息在选择待办事项时都丢失了。
我正在使用 Rails 6.1,但也可以升级到 7。
通过升级到 Rails 7(disable_joins
在 7 中引入)并将 has_and_belongs_to_many
更改为:
解决
# todos_user.rb
class TodosUser < ApplicationRecord
belongs_to :user
belongs_to :todo
end
# todo.rb
class Todo
has_many :todos_users
has_many :users, through: :todos_users, disable_joins: true
end
我有以下数据库结构,模式克隆到 2 个数据库:
users
(身份证,姓名)
todos
(id, title)
todos_users
(user_id, todo_id)
我的软件有 2 个不同的客户,大公司和小公司。分片代表公司自己的待办事项,不想分开。所有用户,包括小公司用户都存储在大公司数据库中。这是因为我们没有单独登录,有些用户可以同时使用大公司和小公司的待办事项列表。
我们在使用这些模型时遇到了以下问题:
# ApplicationRecord connects to the current shard the user is logged to
# GlobalRecord always uses the Big company -database
class User < GlobalRecord
end
class Todo < ApplicationRecord
has_and_belongs_to_many :users
end
结果查询例如 DatabaseProxy.on_shard(shard: :small_company) do Todo.first.users end
SELECT "todos".* FROM "todos" ORDER BY "todos"."id" ASC LIMIT [["LIMIT", 1]]
SELECT "users".* FROM "users" INNER JOIN "todos_users" ON "users"."id" = "todos_users"."user_id" WHERE "todos_users"."todo_id" =
问题来了;它在主分片中加入 todos_users
到 users
!这是有问题的,因为待办事项不在大公司数据库中,而是在小公司数据库中。因此,我插入小型公司数据库 todos_users
的所有信息在选择待办事项时都丢失了。
我正在使用 Rails 6.1,但也可以升级到 7。
通过升级到 Rails 7(disable_joins
在 7 中引入)并将 has_and_belongs_to_many
更改为:
# todos_user.rb
class TodosUser < ApplicationRecord
belongs_to :user
belongs_to :todo
end
# todo.rb
class Todo
has_many :todos_users
has_many :users, through: :todos_users, disable_joins: true
end