Rails 3: SQL-запросы без инъекций - PullRequest
1 голос
/ 31 июля 2010

Мне нравится новый Rail 3!

Новый синтаксис запросов так хорош:

users = User.where(:name => 'Bob', :last_name => 'Brown')

Но когда нам нужно сделать что-то вроде

SELECT * FROM Users WHERE Age >= const AND Money > const2

Мыприходится использовать

users = User.where('Age >= ? and money > ?', const, const2)

Что не очень круто.Следующий запрос небезопасен из-за внедрения SQL:

users = User.where('Age >= #{const} and money > #{const2}')

Мне нравится версия C # / LINQ

var users = DB.Where(u => u.Age >= const && u.Money > const2);

Есть ли способ сделать что-то подобное в Rails?

Ответы [ 4 ]

6 голосов
/ 31 июля 2010

Новый запрос с помощью rails не уязвим для SQL-инъекций.Все кавычки в аргументе экранируются.

Rails 3 AR получил отложенное выполнение, которое LINQ выполнял некоторое время.Это позволяет связать любой из методов запроса.Единственный раз, когда у вас есть , чтобы поместить 2 или более частей в местоположение, это когда вы хотите OR.

Кроме этого, есть много разных способов сделать ваш запрос.*

Users.where('age >= ?', age).where('money > ?', money)
Users.where('age >= ? and money > ?', age, money)

class User < ActiveRecord::Base
  scope :aged, lambda { |age| where('age >= ?', age) }
  scope :enough_money, lambda { |money| where('money > ?', money) }

  scope :can_admit, lambda { |age, money| aged(age).enough_money(money) }
end

Users.aged(18).enough_money(200)
Users.can_admit(18, 200)
3 голосов
/ 31 июля 2010

Возможно, вас заинтересует MetaWhere , с помощью которого вы можете написать:

users = User.where(:age >= const, :money > const2)
2 голосов
/ 31 июля 2010

В Rails 3 вы можете объединить эти выборки вместе. Я не разбираюсь в конкретном синтаксисе, но это хорошее начало: http://railscasts.com/episodes/202-active-record-queries-in-rails-3

Основная концепция заключается в том, что вы можете связать воедино области видимости или положения, и т. Д .:

мета-код здесь:

users = User.where(:age_of_consent).where(:has_credit)

scope :age_of_consent where("age >= ?", 18)
scope :has_credit where("credit > ?", 10)
1 голос
/ 31 июля 2010

Вы можете передать хэш именованных параметров в свой запрос, что является улучшением по сравнению с анонимными позиционными параметрами.

users = User.where('Age >= ? and money > ?', const, const2)

становится (больше похоже на синтаксис LINQ)

users = User.where('Age >= :const and money > :const2', {:const => const, :const2 => const2})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...