Ваша проблема в том, что искатели чувствительны к регистру. У меня точно такая же проблема с моей прежней базой данных.
Попробуйте посмотреть, как это работает:
Person.find_by_Last_Name("Smith")
Это должно сработать.
У меня есть код, который я написал, чтобы исправить подобные проблемы. Это небольшой патч для ActiveRecord, который вы можете вставить в конкретные модели, которые вы хотите изменить.
module ActiveRecord
class Base
# Indicates whether field names should be lowercased for legacy databse fields.
# If true, the field Product_Name will be +product_name+. If false, it will remain +Product_Name+.
# This is false, by default.
cattr_accessor :downcase_legacy_field_names, :instance_writer => false
@@downcase_legacy_field_names = false
end
end
Приведенный выше код создает новый метод доступа в ActiveRecord с именем downcase_legacy_field_names. По умолчанию используется значение false. Когда этот метод доступа имеет значение true в верхней части модели, он вызовет приведенный ниже код.
# set all accessor methods to lowercase (underscore)
# add set_columns_to_lower to each model that needs it
class << ActiveRecord::Base
# Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
# and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
# is available.
def column_methods_hash #:nodoc:
@dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
attr_final = downcase_legacy_field_names ? attr.to_s.downcase : attr
attr_name = attr_final
methods[attr_final.to_sym] = attr_name
methods["#{attr_final}=".to_sym] = attr_name
methods["#{attr_final}?".to_sym] = attr_name
methods["#{attr_final}_before_type_cast".to_sym] = attr_name
methods
end
end
# adapted from: http://wiki.rubyonrails.org/rails/pages/HowToUseLegacySchemas
def downcase_legacy_field_methods
column_names.each do |name|
next if name == primary_key
a = name.to_s.underscore
define_method(a.to_sym) do
read_attribute(name)
end
define_method("#{a}=".to_sym) do |value|
write_attribute(name, value)
end
define_method("#{a}?".to_sym) do
self.send("#{name}?".to_sym)
end
end
end
end
ActiveRecord::Base.downcase_legacy_field_names = true
Этот код был адаптирован с: http://wiki.rubyonrails.org/rails/pages/HowToUseLegacySchemas
В column_methods_hash
мы переопределяем метод ActiveRecord. Этот метод используется для создания списка имен методов, которые создаются во время выполнения для вашей модели базы данных. Мы не хотим переопределять какие-либо ранее в этом процессе, потому что мы бы испортили способность ActiveRecord преобразовывать наши динамические искатели (и другие методы) в соответствующие операторы SQL для устаревшей базы данных.
Второй метод, downcase_legacy_field_methods
, - это новый метод, который фактически генерирует код, который будет выполнять метод downcase'd.
Все вышеперечисленные исправления кода ActiveRecord. Это патч обезьяны, поэтому он может потребоваться где угодно после загрузки ActiveRecord. У меня есть мой в environment.rb.
После того, как вы исправили ActiveRecord, вам нужно будет сделать еще один шаг. В верхней части вашей устаревшей модели базы данных должна быть строка downcase_legacy_field_methods
. Это должно выглядеть примерно так:
class LegacyDatabaseModel < ActiveRecord::Base
downcase_legacy_field_methods
def cubits_to_feet
#conversion code goes here
end
end