ActiveRecord的find方法是否会自动在其参数上调用to_i?

时间:2011-09-23 15:01:14

标签: ruby-on-rails ruby activerecord

我得出结论,ActiveRecord会自动调用其参数上的to_i,但如果有人能够确认,特别是通过引用某些文档,我将不胜感激。

我得出结论的方式最好用以下代码示例说明:

dest_task = WorkEffort.find(params[:task_dest_id])

params[:task_src_ids].split.each do |src_id|
    WorkEffort.find(src_id).move_to_child_of dest_task
end

当我运行以上内容时,只处理了与第一个src_id相关联的记录,尽管我知道task_src_ids参数包含诸如“78,79”之类的内容。通过思考,find必须在该字符串上调用to_i,这将忽略第一个非数字后的所有内容并返回78.

如果find没有调用to_i,则应该产生错误,我必须明确地调用to_i。我当然通过调用“split(',')”来修复代码,现在它处理多个task_src_ids而不是第一个逗号之前的那个。

我知道我自己已经回答了这个问题,但是作为一个Ruby / Rails新手我正在寻找确认,以及相关文档的链接,而且我认为它可以在将来帮助其他人。提前致谢

2 个答案:

答案 0 :(得分:2)

[使用activerecord-2.3.14代码回答此问题,因为您没有指定版本。]

最终,您的价值将通过Quoting#quote方法运行。我已经粘贴了这里的开头,正如您在第15行开始看到的那样,当您的列类型为int时,它将最终调用.to_i传入的值。< / p>

  1 module ActiveRecord
  2   module ConnectionAdapters # :nodoc:
  3     module Quoting
  4       # Quotes the column value to help prevent
  5       # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
  6       def quote(value, column = nil)
  7         # records are quoted as their primary key
  8         return value.quoted_id if value.respond_to?(:quoted_id)
  9           
 10         case value
 11           when String, ActiveSupport::Multibyte::Chars
 12             value = value.to_s
 13             if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
 14               "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
 15             elsif column && [:integer, :float].include?(column.type)
 16               value = column.type == :integer ? value.to_i : value.to_f
 17               value.to_s
 18             else
 19               "'#{quote_string(value)}'" # ' (for ruby-mode)
 20             end

答案 1 :(得分:0)

不确定,因为从现在开始但现在在Rails 6中,如果Active Record的主键是整数(我认为在大多数情况下是to_i),find会自动调用Product.find 10 # #<Product id: 10> Product.find '10' # #<Product id: 10> Product.find '10-ten' # #<Product id: 10> 的参数

var socketsHandler = new SocketsHttpHandler
{
      PooledConnectionIdleTimeout = TimeSpan.FromHours(27),//Actually 5 mins can be idle at maximum. Note that timeouts longer than the TCP timeout may be ignored if no keep-alive TCP message is set at the transport level.
      MaxConnectionsPerServer = 10
};
client = new HttpClient(socketsHandler);

https://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find