我正试图在遗留数据库上放置一个rails面.它是一个旧的Sybase 11数据库安装.我已经得到了一个使用unixODBC和FreeTDS工作的ODBC连接.我也在使用activerecord-odbc-adapter gem.
我必须使用set_table_name和set_primary_key才能使它工作到目前为止.但是,动态的find_by方法都不起作用.我总是得到一个方法遗漏错误.此外,通过关联查找不会同样的错误.正常的模型发现工作,但我希望我可以简写一些.
我是SOL,因为它是一个遗留数据库,或者我可以做什么或检查以使其工作?
如果可以,这将节省我编写SQL的一些工作.
谢谢.
编辑:
控制台输出:
Person.find_by_last_name("Smith") NoMethodError: undefined method `find_by_last_name' for Person(Table doesn't exist):Class from /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1778:in `method_missing' from (irb):1 Person.find(:first, :conditions => { :last_name => "Smith" }) #, Title: "Mr.", First_Name: "Aaron", Middle_Name: "Michael", Last_Name: "Smith", Suffix: nil, Preferred_Name: nil
进一步编辑:
我做了一个疯狂的猜测并将Last_Name大写.返回了一些东西.看起来我将不得不这样做.我仍然不知道协会部分如何工作.那还是个问题.
您的问题是查找程序区分大小写.我的旧数据库存在同样的问题.
试试看它的工作原理:
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