2012-02-21 103 views
7

我在我的形式女巫3場都沒有在我的數據庫:opening_type,OPENING_HOURS,opening_minutes。我想用這3個字段更新主要屬性「開放」(在數據庫中)。導軌 - 添加屬性不是在模型和更新模型屬性

我試過很多東西不起作用。

其實我有:

attr_accessor :opening_type, :opening_hours, :opening_minutes 

    def opening_type=(opening_type) 
    end 
    def opening_type 
    opening_type = opening.split("-")[0] if !opening.blank? 
    end 

    def opening_hours=(opening_hours) 
    end 
    def opening_hours 
    opening_hours = opening.split("-")[1] if !opening.blank? 
    end 

    def opening_minutes=(opening_minutes) 
    end 
    def opening_minutes 
    opening_minutes = opening.split("-")[2] if !opening.blank?  
    end 

我嘗試添加類似:

def opening=(opening) 
    logger.info "WRITE" 

    if !opening_type.blank? and !opening_hours.blank? and opening_minutes.blank? 
     opening = "" 
     opening << opening_type if !opening_type.blank? 
     opening << "-" 
     opening << opening_hours if !opening_hours.blank? 
     opening << "-" 
     opening << opening_minutes if !opening_minutes.blank? 
    end 
    write_attribute(:opening, opening) 
    end 

    def opening 
    read_attribute(:opening) 
    end 

但是,在存取方法不叫,我想opening_type,OPENING_HOURS,opening_minutes是空的太多,如果存取器被稱爲...

我想我並不需要一個before_save回調應該這樣做重寫訪問器。

注: - 的Rails 3.0.5, - opening_type,:OPENING_HOURS,:opening_minutes可能是空的

編輯:我更新了我的代碼

回答

15

注意attr_readerattr_writerattr_accessor只是宏定義自己的方法。

# attr_reader(:foo) is the same as: 
def foo 
    @foo 
end 

# attr_writer(:foo) is the same as: 
def foo=(new_value) 
    @foo = new_value 
end 

# attr_accessor(:foo) is the same as: 
attr_reader(:foo) 
attr_writer(:foo) 

此刻,你的setter方法都沒有做什麼特別的東西,所以如果你只是切換到attr_accessor你的代碼將變得更清潔。

你的另一個問題是,你的opening=方法永遠不會被調用,這是有道理的,因爲在你的代碼中調用它沒有什麼地方。你真正想要的是在你設置好所有的單個零件之後,設置你的開口。現在有做這個非同小可的方式,但Rails的確實有一個before_validation回調,你可以把一個運行值被設置之後,但在驗證運行之前代碼:

class Shop < ActiveRecord::Base 

    attr_accessor :opening_type, :opening_hours, :opening_minutes 

    before_validation :set_opening 

    private 
    def set_opening 
    return unless opening_type && opening_hours && opening_minutes 
    self.opening = opening_type + "-" + opening_hours + "-" + opening_minutes 
    end 
end 
+0

注意這個答案假設你只想在數據庫中存儲結合的'opening'字段。另一種方法是將各個組件存儲在數據庫中,並根據需要動態構建組合字符串。根據您的要求,這可能甚至是更好的方法。 – Gareth 2012-02-21 13:19:14

+0

我得到這個數據庫的開場字段。該數據庫與智能手機應用程序同步,我無法更改其結構以存儲3個不同的字段。 ;-) before_validation回調的問題在於,當我們要編輯表單時...以及我需要在3個變量中截斷開始字段...的形式時,您不處理這種情況。我知道我可以手動做到這一點,但我認爲有更好的方法來做到這一點... – 2012-02-21 13:34:51

+0

所有的事情都是如此,但是你提出的重寫'opening ='的建議會破壞很多東西。另外,使用setter方法非常簡單,它可以完全放棄傳入的參數。最好有一個單獨的方法(比如我的'set_opening'),它明確了它正在做什麼。你不*有*使用before_validation來調用該方法,但我嚴重建議它是一個單獨的方法 – Gareth 2012-02-21 13:43:02

0

代替

attr_reader :opening_type, :opening_hours, :opening_minutes 

你需要

attr_accessor :opening_type, :opening_hours, :opening_minutes 
attr_reader :opening_type, :opening_hours, :opening_minutes 

hf ...

//主要有:opening_type,:OPENING_HOURS,:opening_minutes真正的領域?如果是的話,你只需要這個?

attr_accessor:開放 attr_reader:開放

+0

好吧,我改變了attr_accessor。但開放存取不叫... – 2012-02-21 12:50:47

+0

看到更新,.... – davidb 2012-02-21 12:57:14

+0

號真正的領域是我的數據庫「開放」。我需要從我的表單發送3個字段:opening_type,opening_hours,opening_minuts填充主「開放」字段。這3個字段不在數據庫中。我更新了第一篇文章。 – 2012-02-21 13:04:20