has_many升级ruby和rails版本后关系隐式转换错误
has_many relation implicit conversion error after upgrading ruby and rails version
我刚刚在 rails 项目
上升级了我的 ruby
ruby 1.9.3-p551 至 ruby 2.3.0
和
rails 3.2.13 到 rails 3.2.22 (3-2-稳定)
升级前没有错误。
在我的用户模型中,为了管理用户的联系人,我有一些复杂的关系,在访问这些关系时,我收到 no implicit conversion of nil into String 错误。
关系定义为 -
has_many :contacts, :foreign_key => 'owner_id'
has_many :pending_invited, conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }, through: :contacts, class_name: 'User', source: :user
has_many :invited, conditions: { :'contacts.confirmed' => true }, through: :contacts, class_name: 'User', source: :user
has_many :inverse_contacts, :foreign_key => 'user_id', :class_name => 'Contact'
has_many :pending_invited_by, conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }, through: :inverse_contacts, class_name: 'User', source: :owner
has_many :invited_by, conditions: {:'contacts.confirmed' => true }, through: :inverse_contacts, class_name: 'User', source: :owner
has_many :denied, conditions: {:'contacts.denied' => true }, through: :contacts, class_name: 'User', source: :user
has_many :denied_by, conditions: {:'contacts.denied' => true }, through: :inverse_contacts, class_name: 'User', source: :owner
使用 rails c 我可以通过 运行 -
获得完整的堆栈跟踪
u = User.first
u.pending_invited_by
这会产生以下错误 -
TypeError: no implicit conversion of nil into String
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `initialize'
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `new'
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `sql'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:47:in `block in sanitize'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:45:in `map'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:45:in `sanitize'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:94:in `block in add_constraints'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `each'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `each_with_index'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `add_constraints'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:31:in `scope'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association.rb:99:in `association_scope'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association.rb:88:in `scoped'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/has_many_through_association.rb:178:in `find_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_association.rb:335:in `load_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_proxy.rb:44:in `load_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_proxy.rb:89:in `method_missing'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands/console.rb:47:in `start'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands/console.rb:8:in `start'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
感谢任何帮助。
问题出在条件上了。原始哈希在 3.2.22 下不起作用。
conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }
使用格式更好的散列也不起作用 -
conditions: { contacts: { confirmed: false, denied: false } }
解决方法是改用查询字符串-
conditions: [ '"contacts"."confirmed" = :t1 and "contacts"."denied" = :t2', {t1: false, t2: false} ]
其实,我今天 运行 进入了这个。问题是现代 Ruby (2.3) 与古代 ActiveRecord (3.2.22) 的结合。 Ruby 2.2 没有这个问题。
在 Ruby 2.3 中,Hash
响应 to_proc
,这会触发 ActiveRecord 3.2 中的意外错误。
检查 https://github.com/rails/rails/issues/25010 进一步 detail/discussion。
我的临时解决方法是取消定义 Hash.to_proc
,因为我 100% 确定 none 我的代码或 gems 正在使用它:
class Hash
undef_method :to_proc
end
我刚刚在 rails 项目
上升级了我的 rubyruby 1.9.3-p551 至 ruby 2.3.0
和
rails 3.2.13 到 rails 3.2.22 (3-2-稳定)
升级前没有错误。
在我的用户模型中,为了管理用户的联系人,我有一些复杂的关系,在访问这些关系时,我收到 no implicit conversion of nil into String 错误。
关系定义为 -
has_many :contacts, :foreign_key => 'owner_id'
has_many :pending_invited, conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }, through: :contacts, class_name: 'User', source: :user
has_many :invited, conditions: { :'contacts.confirmed' => true }, through: :contacts, class_name: 'User', source: :user
has_many :inverse_contacts, :foreign_key => 'user_id', :class_name => 'Contact'
has_many :pending_invited_by, conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }, through: :inverse_contacts, class_name: 'User', source: :owner
has_many :invited_by, conditions: {:'contacts.confirmed' => true }, through: :inverse_contacts, class_name: 'User', source: :owner
has_many :denied, conditions: {:'contacts.denied' => true }, through: :contacts, class_name: 'User', source: :user
has_many :denied_by, conditions: {:'contacts.denied' => true }, through: :inverse_contacts, class_name: 'User', source: :owner
使用 rails c 我可以通过 运行 -
获得完整的堆栈跟踪u = User.first
u.pending_invited_by
这会产生以下错误 -
TypeError: no implicit conversion of nil into String
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `initialize'
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `new'
from .bundle/gems/arel-3.0.3/lib/arel.rb:40:in `sql'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:47:in `block in sanitize'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:45:in `map'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/join_helper.rb:45:in `sanitize'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:94:in `block in add_constraints'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `each'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `each_with_index'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:39:in `add_constraints'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association_scope.rb:31:in `scope'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association.rb:99:in `association_scope'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/association.rb:88:in `scoped'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/has_many_through_association.rb:178:in `find_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_association.rb:335:in `load_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_proxy.rb:44:in `load_target'
from .bundle/bundler/gems/rails-f85bbed4cdc1/activerecord/lib/active_record/associations/collection_proxy.rb:89:in `method_missing'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands/console.rb:47:in `start'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands/console.rb:8:in `start'
from .bundle/bundler/gems/rails-f85bbed4cdc1/railties/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
感谢任何帮助。
问题出在条件上了。原始哈希在 3.2.22 下不起作用。
conditions: {:'contacts.confirmed' => false, :'contacts.denied' => false }
使用格式更好的散列也不起作用 -
conditions: { contacts: { confirmed: false, denied: false } }
解决方法是改用查询字符串-
conditions: [ '"contacts"."confirmed" = :t1 and "contacts"."denied" = :t2', {t1: false, t2: false} ]
其实,我今天 运行 进入了这个。问题是现代 Ruby (2.3) 与古代 ActiveRecord (3.2.22) 的结合。 Ruby 2.2 没有这个问题。
在 Ruby 2.3 中,Hash
响应 to_proc
,这会触发 ActiveRecord 3.2 中的意外错误。
检查 https://github.com/rails/rails/issues/25010 进一步 detail/discussion。
我的临时解决方法是取消定义 Hash.to_proc
,因为我 100% 确定 none 我的代码或 gems 正在使用它:
class Hash
undef_method :to_proc
end