开发者

Rails: Using named_scope which triggers a MySQL "in"

PROBLEM:

I want to run a query which would trigger something like

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

using a named_scope.


WHAT I TRIED:

This is for a single code:

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

I tried something like

named_scope :of_codes, lambda {|codes| {:conditions => ["c开发者_开发问答ode in ?", codes]}}

and sent

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

it triggers select * from users where code in '(1,2,4)' which raises a MySQL error because of the extra quotes.

PS: Ideally I would like to send user.of_codes([1,2,4])


This will work just find and not expose you to the SQL injection attack:

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)"

If you want to be a little more slick, you can do this:

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

Then you can call it either with an Array (as above): User.of_codes([1, 2, 3]), or with a list of code arguments: User.of_codes(1, 2, 3).


The simplest approach would be to use a hash for conditions instead of an array:

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

This will work as expected.

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


you can try follwing

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

and

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

EDITED For SQL INJECTION PROBLEM USE

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

and

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜