开发者

Rails 2.3.8: Errors in fetching records since MySQL is case-insensitive and Rails is case-sensitive

开发者 https://www.devze.com 2023-03-15 17:39 出处:网络
I have 2 models with a one-to-one relationship (example is simplified and not the real models). class Person < ActiveRecord::Base

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, :foreig开发者_如何学Gon_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!


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 a before_save filter on each model to update lower_name when the name changes.)

0

精彩评论

暂无评论...
验证码 换一张
取 消