2016-03-08 11 views
0

請注意,這是一個例子,而不是我的實際使用案例。基本概念是什麼我後Ruby on Rails - 使用before_save回調函數應用於多個字段?

(紅寶石版本 - 2.2.1,Rails的版本 - 4.2.4)

假裝我在我的數據庫emailfirst_name領域,我想使用到downcase before_save回調。通常,我會這樣做

before_save :downcase_function 

... 

private 

def downcase_function 
    self.email = email.downcase 
    self.first_name = first_name.downcase 
end 

但是,這不是很靈活或可重複使用。如果我想將此函數添加到last_name字段,該怎麼辦?如果我需要跨多個模型呢?

我希望做的是這樣的事情

#pseudocode - does not work 

before_save :downcase_function(:email, :first_name, :last_name) 

... 

private 

def downcase_function(fields) 
    fields.each do |f| 
    self.f = f.downcase 
    end 
end 

我知道這可能看起來很傻,但我有沒有運氣。

下面是我之後的關鍵事情:

  • 創建一個運行的功能before_save
  • 每個字段指定我的論點允許此功能爲接受參數
  • 應用功能
  • (理想情況下)將其從任何一個模型中抽象出來,以便我可以在任何模型中使用它(如果需要)

非常感謝!

回答

4

也許是這樣的:

ATTRS_TO_DOWNCASE = %i(email first_name last_name) 
before_save :downcase_attrs 

private 
def downcase_attrs 
    ATTRS_TO_DOWNCASE.each do |attr| 
    write_attribute(attr, read_attribute(attr).downcase) 
    end 
end 
+0

這似乎很可靠!我會放棄這一點。不過,我對Rails一般很新,所以你會說你的方法是一個好習慣嗎?只是爲了好奇:) –

+0

使用'read_attribute'和'write_attribute'可能會更清晰。 – tadman

+0

@tadman:我同意...... – spickermann

1

你爲什麼不通過一個進程來before_save,然後調用帶有參數的功能?然後,如果需要,可以將downcase函數提取到其自己的模塊中。

before_save { 
    downcase_function(:email, :first_name, :last_name) 
} 

private 

def downcase_function(*fields) 
    fields.each do |field| 
    self.send "#{field}=", self.send(field).downcase 
    end 
end 
+0

'self.f'不是您可以調用的方法。 ':email.downcase'同樣被破壞。 – tadman

+0

對,對不起。這應該工作。我不確定你是否必須做符號轉換。 – Mohamad