2012-08-16 24 views
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) 

東西線(不能得到它的工作),我曾嘗試合併範圍(顯然是錯誤的做法!)

任何想法 - 我已經在這一天裏頭髮了幾天。

感謝,

史蒂夫

回答

1

一目瞭然,我想這樣的事情,但它很難說,因爲你沒有給我們Site型號:

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

這顯然未經測試,並且很難準確說出,但這裏是發生了什麼的要點:

  1. 急切加載站點,網絡和權限
  2. 強制執行理論SQL語句中概述的條件。

僅供參考,我不記得,如果這種多重條件where作品就像我上面使用,但也許它會得到你的車輪轉動!

+0

謝謝lamvery。網站很簡單: 'class Site :mac_address,:foreign_key =>:mac_address; end' 我看到你正在嘗試做什麼,但它是所有我希望嘗試脫離的硬連線代碼 - 我希望能夠使用示波器來嘗試添加一定程度的靈活性我的代碼(例如'Alarm#any_network'範圍就是一個非常簡單的例子 - 我們有一系列更復雜的查詢,我們想對這組警報進行操作。 Thxs Steve – 2012-08-16 21:32:56

+0

也許混淆是缺乏細節你可以很容易地將上面的例子變成一個類似於scope的例子:'scope:with_permissions,lambda {| user,mask | includes(:site => {:network => permissions})。where([ 'permissions.flags'&&?',mask],'permissions.user_id'=> user)}'並使用它將它鏈接成更復雜的查詢。 – Iamvery 2012-08-17 17:55:54