当前位置:  开发笔记 > 编程语言 > 正文

遗留模式和动态查找(Ruby on Rails)

如何解决《遗留模式和动态查找(RubyonRails)》经验,为你挑选了1个好方法。

我正试图在遗留数据库上放置一个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大写.返回了一些东西.看起来我将不得不这样做.我仍然不知道协会部分如何工作.那还是个问题.



1> salt.racer..:

您的问题是查找程序区分大小写.我的旧数据库存在同样的问题.

试试看它的工作原理:

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

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有