2010-06-30 33 views
2

問題觸發的MySQL:Rails的:使用named_scope其​​中 「中」

我想運行一個查詢可能使用一種named_scope觸發類似

select * from users where code in (1,2,4); 


我的嘗試:

這是一個單碼:

named_scope :of_code, lambda {|code| {:conditions => ["code = ?", code]}} 

我想是這樣

named_scope :of_codes, lambda {|codes| {:conditions => ["code in ?", codes]}} 

和發送

user.of_codes('(1,2,4)') 

它觸發 select * from users where code in '(1,2,4)'由於多餘的引號引起MySQL錯誤。

PS:理想我想送user.of_codes([1,2,4])

回答

4

這將工作只是發現,而不要暴露你的SQL注入攻擊:

named_scope :of_codes, lambda { |codes| 
    { :conditions => ['code in (?)', codes] } 
} 

User.of_codes([1, 2, 3]) 
# executes "select * from users where code in (1,2,3)" 

如果你想多一點圓滑,你可以這樣做:

named_scope :of_codes, lambda { |*codes| 
    { :conditions => ['code in (?)', [*codes]] } 
} 

然後你可以用Array(如上)調用它:User.of_codes([1, 2, 3])或代碼參數列表:User.of_codes(1, 2, 3)

+0

傳遞數組時,您的第二個解決方案不會工作。而不是'[* codes]'use'codes.flatten' – 2010-06-30 20:10:25

+0

你是說要在(?)',[* codes] .flatten]中使用'['代碼嗎?除非你在同一個調用中傳遞非'Array'和'''''',否則'[*]'將會爲你展平。我想,如果你想做'User.of_codes(1,2,[3,4])',那麼你需要'#flatten',但這看起來很尷尬。 – 2010-07-01 18:27:11

2

你可以嘗試follwing

named_scope :of_codes, lambda {|codes| {:conditions => ["code in "+codes]}} 

user.of_codes('(1,2,4)') 

編輯的SQL INJECTION問題,請使用

named_scope :of_codes, lambda {|codes| {:conditions => ["code in (?) ", codes]}} 

user.of_codes([1,2,4]) 
+0

謝謝Salil。我應該明白這一點..。 – Garfield 2010-06-30 11:09:15

+0

這會讓你開放SQL注入攻擊。如果*這些代碼都來自用戶輸入,那麼*您絕不能*使用這種方法。 – 2010-06-30 11:47:41

+0

@james: - 這是我的假設,這些代碼不會來自用戶。 – Salil 2010-06-30 11:53:58

3

最簡單的方法是使用一個哈希值的條件,而不是一個數組:

named_scope :of_codes, lambda { |*codes| { :conditions => { :code => codes } } } 

預期這將工作。

User.of_codes(1, 2, 3) # => SELECT ... code IN (1,2,3) 
User.of_codes(1) # => SELECT ... code IN (1) 
+0

我不確定何時添加此支持。它當然適用於我的所有Rails 2.3.x應用程序,但它可能不適用於較舊的應用程序。 – 2010-07-01 18:28:45