有没有更好的方法在rails中创建只读属性?

时间:2013-11-23 03:59:48

标签: ruby-on-rails ruby module

我在Rails中创建一个ActiveRecord对象,我希望它具有只读属性。我最初尝试使用attr_readonly,但很惊讶地发现它:

  1. Disabled mass-updating of those properties, even on new records
  2. 如果记录已保存,则未引发异常,或通知您以任何方式更改了只读属性。
  3. 我想要这两个功能;这是我尝试实施的:

    # 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的新手,所以我也很感激任何风格的评论。

1 个答案:

答案 0 :(得分:3)

你试过这个:

class Model < ActiveRecord::Base    
  before_save :protect_attributes

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

另一个想法是,为什么要在模型级别强制执行此操作呢?只读属性和只能在控制器的create动作中写入的属性有什么区别?你总是可以这样做:

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