2009-02-11 57 views
3

我試圖把一個軌道面舊的數據庫上。這是一箇舊的數據庫安裝。我得到了一個ODBC連接, 使用unixODBC和FreeTDS工作。我也使用 activerecord-odbc-adapter gem。傳統模式和動態查找(Ruby on Rails的)

我不得不使用set_table_name和set_primary_key,使其工作這麼 爲止。但是,動態find_by方法都不起作用。我總是得到一個 方法缺少錯誤。而且,通過關聯發現並不能像 那樣工作,並且具有相同的錯誤。在模型上的正常發現工作,但我是 希望我能簡化一些這一點。

上午我SOL上,是因爲它是一個傳統的DB或者是有什麼我可以做 或檢查,使這項工作?

如果可以,那會救我一些工作編寫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" }) 

#<Person Person_ID: <redacted>, Title: "Mr.", First_Name: "Aaron", Middle_Name: "Michael", Last_Name: "Smith", Suffix: nil, Preferred_Name: nil 

進一步編輯:

我把胡亂猜測和資本LAST_NAME。這返回了什麼。看起來我必須這樣做。我仍然不知道協會部分如何工作。這仍然是一個問題。

回答

5

你的問題是,發現者是區分大小寫的。我與我的遺留數據庫有同樣的確切問題。

試試這個看它的工作:

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 
1

這是否工作:

User.find(:all, :conditions => ['name = ?', "bob"]) 

...雖然這不?

User.find_all_by_name("bob") 

(這應該是一個評論,但我是新建的,不能評論尚未:) 堆棧跟蹤會幫我挖通,看看發生了什麼事情。 您使用的是哪種版本的導軌?

+0

正確。正常找到工作。我正在使用2.2.2。當我嘗試做我提到的事情時,我會發布我的控制檯所說的內容。 – 2009-02-11 23:02:37

2

我遇到過類似的問題,這沒有命名約定嵌入到傳統的SQL Server數據庫的ASP.net代碼廣闊的擴張與SQL代碼隱藏頁面等,這排除我們修改了現有的ASP.net應用程序,而不是我想這樣做。

這個數據庫結構對於rails非常痛苦,我們認爲,因爲表名都是單數,所以我們可以重命名所有表和列以與Rails保持一致,然後創建反映原始表/列結構的視圖ASP.net應用程序。

這使我們能夠對新更名的表格進行更改,包括添加新字段等,同時將遺留應用程序與這些數據庫結構更改隔離。

這個解決方案顯然不適用於所有人,但它對我們來說證明是非常成功的。