2010-01-15 69 views
0

考慮遷移如何2分貝列映射到一個屬性

class CreateTalks < ActiveRecord::Migration 
    def self.up 
    create_table :talks do |t| 
     t.integer :duration_hours 
     t.integer :duration_minutes 
    end 
    end 

    def self.down 
    drop_table :talks 
    end 
end 

和模型

class Talk < ActiveRecord::Base 
end 

和對象

class Duration 
    attr_accessor :hours, :minutes 
end 

我怎麼映射DURATION_HOURS和DURATION_MINUTES列Talk中的Duration屬性,以便我可以做

d = Talk.first.duration 
hours = d.hours 
minutes = d.minutes 

我知道在這種情況下,我可以將小時和分鐘轉換爲秒,並將它們存儲在單個列中,但我期望瞭解如何使用ActiveRecord實現這種類型的映射。

回答

0

編寫自定義訪問器方法。

+1

你能否展開一下,你的意思是說我添加了duration_hours和duration_minutes的存取方法來填充持續時間屬性?如果是這種情況,他們需要成爲公衆訪問者還是可以讓他們變成私人的? (我想封裝duration_hours和duration_minutes,以便應用程序的其餘部分只使用duration屬性) – opsb 2010-01-15 23:49:25

+0

我會寫兩種方法(duration =(setter)和duration(getter))。首先解析傳遞的字符串(以任何可能的格式),並適當設置小時和分鐘的持續時間,第二個 - 從db中獲取這兩個值,並以任意格式將它們組合在一起。 但開始 - 我會保持持續時間爲整數秒。或者,如果你需要更好的精度,如浮點數。 – Eimantas 2010-01-16 08:55:13

0

我不知道我明白你想要完成什麼......特別是在兩個不同的列中存儲小時和分鐘,而不是存儲日期/時間和提取小時和分鐘.... buuuut。 ..我的attr_accessor的理解是:

attr_accessor :duration_hours 

等於:

def duration_hours 
    @duration_hours 
end 

def duration_hours=(d) 
    write_attribute(:duration_hours, d) 
end 

那麼什麼Eimantas指的是自定義上面的方法來存儲或您認爲合適的顯示信息......你應該已經能夠做到了:

d = Talk.first 
hours = d.duration_hours 
minutes = d.duration_minutes 

對不對?

編輯:

如果你想使演講或某事的名單和時間分別使用您的列經過的量,我會做的方式是(僅用於顯示):

def duration 
    @duration = self.duration_hours.to_s + ":" + self.duration_minutes.to_s 
end 

然後使用talk.duration調用。馬虎,但它的作品。

+0

回想起來,我認爲我的思維被我對java的ORM框架(如hibernate)的經驗所籠罩。在休眠的情況下,數據庫表和模型可以完全不同,通過定義映射來實現。我開始意識到active_record模式的完整意圖,即模型和數據庫表之間沒有區別。如上所述,必須使用自定義訪問器來實現表示中的任何差異。 – opsb 2010-01-16 02:50:59

+0

我有一個很小的感覺,這是一個稍微低效的方法,因爲每次訪問者被調用時都必須完成翻譯。這與檢索模型時執行一次翻譯相反。但是,從實用的角度來看,自定義訪問器可能只會按請求調用一次,在這種情況下效率問題無論如何都是學術問題。 – opsb 2010-01-16 02:52:00

+0

順便說一下,我不想使用時間列的原因是它表達了完全不同的意圖。它意味着與相對點相對的時間點,例如,開始時間後1小時(start_time也包含在真實模型中)。也許我應該去開始/結束時間而不是開始/持續時間,但是模型會經常被移動一段時間,所以它看起來更合適。通過使用開始/持續時間,移動只需要更新一列。這也是對用戶具有的概念模型的更準確反映。 – opsb 2010-01-16 02:57:30