【问题标题】:How to join multiple table with multiple where如何将多个表与多个位置连接起来
【发布时间】:2021-05-07 06:39:13
【问题描述】:

我的目的是让所有与school_admindormitory_admin 有关系的用户

所以这里是表格。

users (has one school_admin or has one dormitory_admin)
-id
-username

has_one :school_admin
has_one :dormitory_admin

school_admins (pivot table)
-id
-school_id
-user_id

belongs_to :user
belongs_to :school

dormitory_admins (pivot table)
-id
-dormitory_id
-user_id

school (has many dormitory)
-id
-name

has_many :dormitories

dormitory (belongs to one school)
-id
-school_id

这是我当前的查询(我现在有 2 个查询,我需要将其合并为一个查询)

@q1 = User.joins(:school_admin).where(school_admin: { school_id: current_user.school_admin.school_id }).select("users.id, users.username, school_admin.name, school_admin.phone").ransack(params[:q])
@q2 = User.joins(:dormitory_admin).where(dormitory_admin: { dormitory_id: current_user.school_admin.school.dormitories.pluck(:id) }).select("users.id, users.username, dormitory_admin.name, dormitory_admin.phone").ransack(params[:q])

我使用 ransack gem 进行表过滤,使用 PostgreSQL 进行数据库。

我可以使用像ActiveRecord::Base.connection.execute(sql) 这样的纯 SQL 来执行“UNION”,但如果我使用它,ransack gem 将无法工作。

【问题讨论】:

  • 可以添加关联吗
  • 已更新,先生,请查看我的新更新帖子
  • @mrobbizulifkar 现在检查我已经更新了我的答案。

标签: ruby-on-rails ruby postgresql ruby-on-rails-6


【解决方案1】:

您可以在现有作用域上使用 to_sql,然后将其粘贴在 from 子句中

 query1 =  User.joins(:school_admin).where(school_admin: current_user.school_admin).select("users.id, users.username, school_admins.name, school_admins.phone")
    
 query2 = User.joins(:dormitory_admin).where(dormitory_admin: current_user.dormitory_admin).select("users.id, users.username, dormitory_admins.name, dormitory_admins.phone")
    
    
 User.from("(#{query1.to_sql} UNION #{query2.to_sql}) AS users").ransack(params[:q])
    
    
    SELECT "users".* FROM (
        SELECT 
        users.id, 
        users.username, 
        school_admins.name, 
        school_admins.phone 
        FROM "users" 
        INNER JOIN "school_admins" 
        ON "school_admins"."user_id" = "users"."id" 
        WHERE "users"."id" = 1 
        UNION 
        SELECT 
        users.id, 
        users.username, 
        dormitory_admins.name, 
        dormitory_admins.phone 
        FROM "users" 
        INNER JOIN "dormitory_admins" 
        ON "dormitory_admins"."user_id" = "users"."id" 
        WHERE "users"."id" = 2) 
    AS users;

或者更好的方法是避免重复查询

User.from("(#{User.joins(:school_admin).where(school_admin: current_user.school_admin).select("users.id, users.username, school_admins.name, school_admins.phone").to_sql} UNION #{User.joins(:dormitory_admin).where(dormitory_admin: current_user.dormitory_admin).select("users.id, users.username, dormitory_admins.name, dormitory_admins.phone").to_sql}) AS users").ransack(params[:q])

注意:我使用的表名是复数school_admins & dormitory_admins。另外,我修改了 query1 & query2 中的 where 子句

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2021-12-06
    • 2015-05-04
    相关资源
    最近更新 更多