Rails 2.3.8:由于 MySQL 不区分大小写而 Rails 区分大小写,因此获取记录时出错
我有两个具有一对一关系的模型(示例是简化的,而不是真实的模型)。
class Person < ActiveRecord::Base
belongs_to :student, :foreign_key => 'name', :primary_key => 'full_name'
end
class Student < ActiveRecord::Base
belongs_to :person, :foreign_key => 'full_name', :primary_key => 'name'
end
它们之间的链接是弱链接,因为可以更改 Student 对象中的 full_name 字段,然后无法从 Student 对象访问 person 对象。
到目前为止一切顺利(这是设计使然)。
当一个人的名字与同等学生的全名相同,但字母大小写不同时,就会出现问题。
对 MySQL DB 的查询返回结果(因为 MySQL 不区分大小写), 但是当 Rails 运行结果时它找不到它(因为 Rails 区分大小写), 这会在急切加载关联时导致错误。 错误堆栈跟踪示例:
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each):
vendor/rails/activerecord/lib/active_record/association_preload.rb:155:in `set_association_single_records'
...
我猜这是 Rails 2.3.8 的一个错误。 对于这个问题有一个简单的解决方案吗?
谢谢!
I have 2 models with a one-to-one relationship (example is simplified and not the real models).
class Person < ActiveRecord::Base
belongs_to :student, :foreign_key => 'name', :primary_key => 'full_name'
end
class Student < ActiveRecord::Base
belongs_to :person, :foreign_key => 'full_name', :primary_key => 'name'
end
The link between them is a weak link, since one can change the full_name field in the Student object and then the person object couldn't be reached from the student object.
So far so good (this is by design).
The problem arises when a person's name is the same as an equivalent student's full_name, but different in the letters' case.
The query for the MySQL DB returns a result (since MySQL is case-insensitive),
but when Rails runs over the result it doesn't find it (since Rails is case-sensitive),
which results in an Error when eagerly loading the association.
Example of the error's stacktrace:
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each):
vendor/rails/activerecord/lib/active_record/association_preload.rb:155:in `set_association_single_records'
...
I'm guessing this is a Rails 2.3.8 bug.
Is there an easy solution for this problem?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,这不是 Rails 错误或 Ruby 错误 - Ruby 字符串区分大小写,因此您不应期望它按原样工作。
这是糟糕的数据库设计,但如果您想继续走这条疯狂之路,请向每个名称强制小写的表添加一个单独的列
lower_name
,并将其用作 AR 关联链接。 (最干净的解决方案是在每个模型上放置一个before_save
过滤器,以便在名称更改时更新lower_name
。)No, this is not a Rails bug or a Ruby bug - Ruby strings are case-sensitive, so you should not expect this to work as is.
This is bad database design, but if you want to keep going down this road of madness, add a separate column
lower_name
to each table that has the name forced to lowercase and use that as your AR association link. (The cleanest solution is to put abefore_save
filter on each model to updatelower_name
when the name changes.)