В чем разница между `?` И именем запроса в Active Record? - PullRequest
0 голосов
/ 08 января 2019

Я знаю, что первый запрос безопасен:

foo.where('name LIKE ?', "%#{search}%")

но я не уверен насчет второго?

foo.where('name Like :search', search: "%#{search}%")

Ответы [ 2 ]

0 голосов
/ 08 января 2019

И 'name LIKE ?', и 'name Like :search' используют подготовленные операторы, которые избегают значений и, таким образом, защищены от атаки SQL-инъекцией в отличие от "name LIKE %#{search}%", который использует конкатенацию строк.

Единственное отличие состоит в том, как объявляются связанные переменные. ? является позиционным заполнителем, а :search является именованным заполнителем.

Использование позиционных или именованных заполнителей действительно влияет только на читабельность вашего кода.

# really no point in a named placeholder here
Foo.where('a = ?', 1)
Foo.where('a = :a', a: 1)

# positional arguments can get confusing if there a lot of them
Foo.where('a = ? AND b = ? AND c = ?', 1, 2, 3)
Foo.where('a = :a AND b = :b AND c = :c', a: 1, b: 2, c: 3)

# this is where a named placeholder shines
Foo.where('a = ? AND (b = ? OR c = ?)', foo.name, foo.name, foo.id)
Foo.where('a = :name AND (b = :id OR c = :name)', name: foo.name, id: foo.id)

Особенности проектирования очень похожи на использование позиционных и именованных аргументов в методах.

0 голосов
/ 08 января 2019

Второе тоже безопасно. Посмотрите примеры в ActiveRecord::Sanitization::ClassMethods: https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html

Например:

sanitize_sql_array(["name=? and group_id=?", "foo'bar", 4])
# => "name='foo''bar' and group_id=4"

sanitize_sql_array(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
# => "name='foo''bar' and group_id=4"

sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
# => "name='foo''bar' and group_id='4'"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...