参数化加入 Rails 4
Parametrized join in Rails 4
我正在做手册 join
,我需要将参数传递给它的 ON
子句:
Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{baz}")
有没有办法将 baz
作为参数传递,以避免潜在的注入问题?有一种方法 sanitize_sql_array
,但我不确定在这种情况下如何使用它。
注意:我不能使用where
,因为它不一样。
我认为你应该这样尝试:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id AND bars.baz = ?", baz)
更多参数:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = ? AND bars.baz = ? AND ...", foo, baz, etc...)
如果您传递值的哈希值,您应该是安全的,AR 将保护您免受 SQL 注入,如下所示:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id").where(bars: {baz: baz})
只是不要在 sql 中使用易受 sql 注入攻击的行字符串。
如果是 sanitize_sql_array,那就是:
# Warning: sanitize_sql_array is a protected class method, be aware of that to properly use it in your code
ar = ["LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = %s", baz]
# Within a class method in foo model:
sanitized_sql = sanitize_sql_array(ar)
Foo.joins(sanitized_sql)
试过了,成功了。
活动记录模型有 sanitize
class 方法,所以你可以这样做:
Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{Foo.sanitize(baz)}")
__
它已从 rails 5.1 开始删除,请改用 ActiveRecord::Base.connection.quote()
Arel 可以做到。
baz = "i am a baz"
foos = Arel::Table.new('foos') # or Foo.arel_table, if this is an AR model
bars = Arel::Table.new('bars')
join = foos.outer_join(bars).on(
foos[:id].eq(bars[:foo_id]),
bars[:baz].eq(baz))
puts join.to_sql
这会产生
SELECT FROM "foos"
LEFT OUTER JOIN "bars" ON
"foos"."id" = "bars"."foo_id"
AND "bars"."baz" = 'i am a baz'
现在,如果您想将其返回到 ActiveRecord 查询中,而不仅仅是打印 SQL:
Foo.joins(join.join_sources)
我正在做手册 join
,我需要将参数传递给它的 ON
子句:
Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{baz}")
有没有办法将 baz
作为参数传递,以避免潜在的注入问题?有一种方法 sanitize_sql_array
,但我不确定在这种情况下如何使用它。
注意:我不能使用where
,因为它不一样。
我认为你应该这样尝试:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id AND bars.baz = ?", baz)
更多参数:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = ? AND bars.baz = ? AND ...", foo, baz, etc...)
如果您传递值的哈希值,您应该是安全的,AR 将保护您免受 SQL 注入,如下所示:
Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id").where(bars: {baz: baz})
只是不要在 sql 中使用易受 sql 注入攻击的行字符串。
如果是 sanitize_sql_array,那就是:
# Warning: sanitize_sql_array is a protected class method, be aware of that to properly use it in your code
ar = ["LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = %s", baz]
# Within a class method in foo model:
sanitized_sql = sanitize_sql_array(ar)
Foo.joins(sanitized_sql)
试过了,成功了。
活动记录模型有 sanitize
class 方法,所以你可以这样做:
Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{Foo.sanitize(baz)}")
__
它已从 rails 5.1 开始删除,请改用 ActiveRecord::Base.connection.quote()
Arel 可以做到。
baz = "i am a baz"
foos = Arel::Table.new('foos') # or Foo.arel_table, if this is an AR model
bars = Arel::Table.new('bars')
join = foos.outer_join(bars).on(
foos[:id].eq(bars[:foo_id]),
bars[:baz].eq(baz))
puts join.to_sql
这会产生
SELECT FROM "foos"
LEFT OUTER JOIN "bars" ON
"foos"."id" = "bars"."foo_id"
AND "bars"."baz" = 'i am a baz'
现在,如果您想将其返回到 ActiveRecord 查询中,而不仅仅是打印 SQL:
Foo.joins(join.join_sources)