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

Max*_*iel 3 ruby module ruby-on-rails

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

  1. 禁止大规模更新这些属性,即使在新记录上也是如此
  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
Run Code Online (Sandbox Code Playgroud)

然后在我的模型中:

class Model < ActiveRecord::Base

  include ReadOnlyAttributes

  def read_only_attributes
    [:event_type]
  end

end
Run Code Online (Sandbox Code Playgroud)

是否有内置或更好的方法来获取满足上述要求的只读属性?

我还是Ruby / Rails的新手,所以我也希望能收到任何风格上的评论。

Max*_*Max 5

您是否尝试过:

class Model < ActiveRecord::Base    
  before_save :protect_attributes

  private
  def protect_attributes
     false if !new_record? && event_type_changed?
  end
end
Run Code Online (Sandbox Code Playgroud)

另一个想法是,为什么要在模型级别上强制执行呢?只读属性和只能在控制器的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
Run Code Online (Sandbox Code Playgroud)