Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 连接3个表并检索关联的对象_Ruby On Rails_Join - Fatal编程技术网

Ruby on rails 连接3个表并检索关联的对象

Ruby on rails 连接3个表并检索关联的对象,ruby-on-rails,join,Ruby On Rails,Join,试图学习rails 3并与一个辅助项目连接,但遇到了一个连接,我不太清楚。以下是课程: class Stuff belongs_to :user has_many :things end class Thing belongs_to :user belongs_to :stuff end class User has_many :stuffs has_many :things end 以下是示例数据: Stuff Thing

试图学习rails 3并与一个辅助项目连接,但遇到了一个连接,我不太清楚。以下是课程:

class Stuff
  belongs_to :user
  has_many :things
end

class Thing
  belongs_to :user
  belongs_to :stuff
end

class User
  has_many :stuffs
  has_many :things
end
以下是示例数据:

Stuff            Thing                     User
id|user_id|data  id|user_id|stuff_id|data  id
--|-------|----  --|-------|--------|----  --
1 |2      |n     1 |1      |nil     |m     1
2 |3      |o     2 |3      |2       |p     2
                 3 |3      |nil     |q     3
                                           4
我想返回:

  • 所有同时具有A和B的用户,以获得用户A和B, 及
  • 所有具有A或B的用户,以获取用户A或用户B 还有组合
  • 对上述数据的查询将产生以下结果:

    Stuff    Thing        User
    --------------------------
    nil      1|1|nil|m    1
    1|2|n    nil          2
    2|3|o    2|3|2|p      3
             3|3|nil|q    3
    
    可以进行如下的一些内部连接,然后使用ruby删除只有A的用户或只有B的用户,这些用户的结果与A和B重叠

    User.includes(:as,:bs).joins(:as, :bs)
    User.includes(:as).joins(:as)
    User.includes(:bs).joins(:bs)
    

    关于如何使用单个联接(原始sql或活动记录查询接口)来完成这一切,您有什么想法吗?

    提出了一个使用联合的解决方案。不幸的是,Rails关系不支持UNION,但可以使用find_by_sql和paginate_by_sql。下面是实际代码的精简版本:

        all = User.paginate_by_sql(
        "SELECT u.id as u_id,
            s.id as s_id,
            cast(null as integer) t_id,
            s.created_at as created_at
        FROM users u
        INNER JOIN stuffs s on s.user_id = u.id where s.thing_id is null
        UNION
        SELECT u.id as u_id,
            cast(null as integer) s_id,
            t.id as t_id
            t.created_at as created_at
        FROM users u
        INNER JOIN things on t.user_id = u.id
        WHERE t.id not in (SELECT things_id FROM s)
        UNION
        SELECT u.id as u_id,
            s.id as s_id,
            t.id as t_id
            s.created_at as created_at
        FROM users u
        INNER JOIN stuffs s on s.user_id = u.id
        INNER JOIN things t on t.user_id = u.id
        ORDER BY created_at", :page => 1, :per_page => 50)