2014-08-28 73 views
0

我想創建一個名爲'Persona'的模型(它屬於User模型)。用戶在表單中選擇一個名稱,然後單擊創建按鈕,因此我需要角色模型中的屬性「名稱」。我還希望Persona模型具有角色名稱的小寫版本,所以我需要第二個屬性'downcase_name'。例如,用戶可以選擇角色的名字爲Fooey Barman,所以downcase_name將是fooey酒保。創建一個模型

我的問題是,你如何初始化downcase_name屬性?你把它放在Persona控制器中嗎?在新的或創建的方法?例如:

def create 
    @persona = Persona.new(persona_params) 
    @persona.downcase_name = @persona.name.downcase 
    if @persona.save 
    flash[:success] = "Welcome, " + @persona.name 
    redirect_to @persona 
    else 
    render 'new' 
    end 
end 

還是你把它放在模型中?

class Persona < ActiveRecord::Base 
    before_create :make_downcase_name 
    validates :name, presence: true, length: { maximum: 50 } 
    private 
    def make_downcase_name 
     self.downcase_name = name.downcase 
    end 
end 

或者也許這樣?

class Persona < ActiveRecord::Base 
    validates :name, presence: true, length: { maximum: 50 } 
    validates :downcase_name, presence: true 
end 

編輯:

所以,我是正確的思維做的是在模型的方式,用before_save和驗證,這樣?:

class Persona < ActiveRecord::Base 
    before_save :make_downcase_name 
    validates :name, presence: true, length: { maximum: 50 } 
    validates :downcase_name, presence: true 
    private 
    def make_downcase_name 
     self.downcase_name = name.downcase 
    end 
end 

回答

0

使用before_*回調看起來非常習慣。或者,您還可以在控制器中創建一個服務對象(如PersonaCreator),以處理邏輯並在模型上設置適當的屬性。

請注意,before_create將只被調用一次,這意味着如果用戶稍後更改角色的名稱,則不會調用回調。您可能想要執行類似before_save的操作,並檢查名稱是否已更改。

+0

@fivedigit博客文章提醒您不要使用特定類型的回調用法,例如,延伸到模型主要職責之外的回調 - 這似乎是,正如您在答案中所述。 – 2014-08-28 16:55:23

+0

恐怕我不明白。你是說我需要把這樣的東西放在控制器的某個地方:downcase_name = name.downcase。 – Bazley 2014-08-29 17:13:17

+0

不是。我在說,之前回調的使用非常好,非常常見。但是,如果您發現自己處於有很多回調的情況,那麼將邏輯移至單獨的對象(PersonaCreator)可能會更好。該對象將在控制器中實例化,並傳遞請求參數。在它內部會創建一個'Persona'模型的新實例,執行邏輯(設置downcase_atribute等)並將未保存的實例返回給控制器進行保存(以便您可以輕鬆處理驗證錯誤)。 – 2014-08-29 21:00:19