0

我在不同(并且有些关联)模型上有几个范围

class Alarm
   has_one :site #use mac_address field in Alarm and Site as key / foreign key

   scope :any_network, lambda{ joins(:network) } #more complex stuff can be done :-)
   #etc
end

class Network
   has many :permissions
   has_many :sites

   scope :has_permission, lambda{|level, user| #etc - returns a list of networks that a                  
                                               # user has the `level` permission for }

   #etc
end

class Permission
    has_one :network, :user
    #etc -uses a flags field to hold permision levels
end

所以我可以

Alarm.any_network

这会产生

SELECT `alarm`.* FROM `alarm` INNER JOIN `site` ON 
`site`.`mac_address` = `alarm`.`mac_address` INNER JOIN `network` ON 
`network`.`id` = `site`.`network_id`

我能做到

Network.has_permission('manager',1) 

这会产生

SELECT `network`.* FROM `network` INNER JOIN `permission` ON 
`permission`.`network_id` = `network`.`id` 
WHERE (permission.user_id = 1 and permission.flags && 8)

这就是它应该的样子。

我无法解决的是如何加入这两个范围以生成源自用户具有适当权限的任何网络的所有警报的集合。类似的东西

SELECT `alarm`.* FROM `alarm` INNER JOIN `site` 
ON `site`.`mac_address` = `alarm`.`mac_address` 
INNER JOIN `network` ON `network`.`id` = `site`.`network_id` 
INNER JOIN `permission` ON `permission`.`network_id` = `network`.`id` 
WHERE (permission.user_id = 1 and permission.flags && 8)

我尝试链接范围(无法使其工作)并且我尝试合并范围(显然是错误的做法!)

任何想法——这几天我一直在扯头发。

谢谢,

史蒂夫

4

1 回答 1

1

乍一看,我想像这样,但很难说,因为你没有给我们Site模型:

Alarm.includes(:site => {:network => :permissions}).where(['permissions.flags' && ?', 8], 'permissions.user_id' => 1)

这显然是未经测试的,很难准确地说,但这里是发生了什么的要点:

  1. 渴望加载站点、网络和权限
  2. 强制执行您在理论 SQL 语句中概述的条件。

仅供参考,我不记得这种多重条件是否where像我上面使用的那样工作,但也许它会让你的轮子转动!

于 2012-08-16T19:37:14.557 回答