Не пытайтесь сделать это: (пояснение ниже)
Вы можете использовать модуль ActiveRecord :: Sanitization и написать что-то вроде следующего, внутриваша модель ActiveRecord:
AExample.joins("INNER JOIN b_examples ON b_examples.#{sanitize_sql(field_name)} = a_examples.#{sanitize_sql(field_name)}")
Или вы можете включить модуль где-нибудь еще и использовать его там (например, ваш контроллер).
Используйте это вместо этого: (включено из другого ответа)
AExample.joins("INNER JOIN b_examples ON b_examples.#{ActiveRecord::Base.connection.quote_column_name(field_name)} = a_examples.#{ActiveRecord::Base.connection.quote_column_name(field_name)}")
Если столбец не будет найден, возникнет ошибка, которая не позволит вредоносному коду ввести ваш запрос.
Однако я бы не стал этого делатьв моем приложении это выглядит подозрительно, другие программисты могут не понимать, что происходит, оно может быть реализовано неправильно, должно быть включено тщательное тестирование, оно может иметь ошибки и тому подобное.В вашей задаче вам нужно только построить два разных запроса, с этой информацией я напишу что-то вроде:
case dynamic_field
when 'field_x'
AExample.joins('INNER JOIN b_examples ON b_examples.field_x = a_examples.field_x')
when 'field_y'
AExample.joins('INNER JOIN b_examples ON b_examples.field_y = a_examples.field_y')
else
raise "Some suspicious parameter was sent!: #{dynamic_field}"
end
Или даже напишу scopes в вашей модели и не используйте этот код.летать
При таких проблемах, как, например, с шифрованием, попытайтесь найти обходной путь и по возможности избегайте реализации собственных решений.
РЕДАКТИРОВАТЬ:
Метод sanitize_sql
предназначен для санации условий для предложения WHERE ( ActiveRecord :: Sanitization ):
Принимает массив или строку условий SQL и санирует их вдопустимый фрагмент SQL для предложения WHERE.
Это не вариант, так как вы пытаетесь выполнить санитарную обработку для условия INNER JOIN
или ON
.
Обратите внимание, что модуль ActiveRecord::Sanitization
имеет опции только для WHERE, SET, ORDER и LIKE.Мне не удалось найти метод очистки для имени столбца, INNER JOIN или предложения ON.Возможно, это полезная функциональность, которую следует добавить в Rails в следующей версии.
Использование sanitize_sql
со строкой передает ее почти без фильтрации, поэтому, если переменная field_name
содержит некоторый вредоносный код в виде:
"field_x = a_examples.field_x; DROP TABLE a_examples; --"
Он будет включен в ваш запрос, без каких-либо ошибок. .
Это решение небезопасно, и по таким причинам мы должны избегать написания кодаэта природа.Возможно, вы найдете что-то полезное с Arel
или другими драгоценными камнями, но я бы настоятельно рекомендовал этого не делать.
РЕДАКТИРОВАТЬ 2:
Добавлено рабочее решение для экранирования столбцаназвание.При вводе вредоносного кода возникает ошибка, поскольку столбец с таким именем не будет найден.