2013-11-23 24 views
2

我在Rails中創建了一個ActiveRecord對象,我想擁有隻讀屬性。我最初嘗試使用attr_readonly而是驚愕地發現它:有沒有更好的方法在rails中創建只讀屬性?

  1. Disabled mass-updating of those properties, even on new records
  2. 沒有引發異常,如果記錄被保存後,或通知您在任何方式改變了只讀屬性。

我想要這兩個功能;這是我在嘗試實現:

# For use with ActiveRecord 

module ReadOnlyAttributes 

    class ReadOnlyAttributeException < StandardError 
    end 

    def create_or_update # Private, but its what every method gets funneled through. 
    if !self.new_record? && self.respond_to?(:read_only_attributes) 
     changed_symbols = self.changed.map(&:to_sym) 
     if changed_symbols.intersect?(self.read_only_attributes) 
     raise ReadOnlyAttributeException, "Readonly attributes modified on #{self.class}: #{changed_symbols & self.read_only_attributes}" 
     end 
    end 

    super 
    end 

end 

然後在我的模型:

class Model < ActiveRecord::Base 

    include ReadOnlyAttributes 

    def read_only_attributes 
    [:event_type] 
    end 

end 

是否有一個內置的或更好的方式來獲得滿足上述要求的只讀屬性?

我對Ruby/Rails還很新,所以我也很感謝任何風格的評論。

回答

3

你有沒有嘗試過這樣的:

class Model < ActiveRecord::Base  
    before_save :protect_attributes 

    private 
    def protect_attributes 
    false if !new_record? && event_type_changed? 
    end 
end 

另一個想法是,爲什麼還要在模型級別執行呢?只讀屬性和只能在控制器的創建操作中寫入的屬性之間有什麼區別?你總是可以這樣做:

class EventController < ActionController::Base 
    def create 
    @event = Event.new params.require(:event).permit :event_name, :event_type 
    end 

    def update 
    @event = Event.find(params[:id]).update params.require(:event).permit(:event_name) 
    end 
end 
+0

這很好,謝謝!此特定對象用於內部記錄保存,並且沒有面向公衆的控制器。 – MaxGabriel

+0

很高興我能幫到你。另一個稍微好一點的方法是使用自定義驗證器。 – Max

相關問題