Module: ActiveRecord::ReadonlyAttributes::ClassMethods
| Relationships & Source Files | |
| Defined in: | activerecord/lib/active_record/readonly_attributes.rb |
Instance Method Summary
-
#attr_readonly(*attributes)
::ActiveRecord::Attributeslisted as readonly will be used to create a new record. -
#readonly_attributes
Returns an array of all the attributes that have been specified as readonly.
- #define_method_attribute=(canonical_name, owner:, as: canonical_name) private
- #readonly_attribute?(name) ⇒ Boolean Internal use only
Instance Method Details
#attr_readonly(*attributes)
::ActiveRecord::Attributes listed as readonly will be used to create a new record.
Assigning a new value to a readonly attribute on a persisted record raises an error.
By setting config.active_record.raise_on_assign_to_attr_readonly to false, it will
not raise. The value will change in memory, but will not be persisted on save.
Examples
class Post < {ActiveRecord::Base}
attr_readonly :title
end
post = {Post.create!}(title: "Introducing Ruby on Rails!")
post.title = "a different title" # raises {ActiveRecord::ReadonlyAttributeError}
post.update(title: "a different title") # raises {ActiveRecord::ReadonlyAttributeError}
# File 'activerecord/lib/active_record/readonly_attributes.rb', line 32
def attr_readonly(*attributes) attributes = attributes.map(&:to_s) self._attr_readonly = ActiveSupport::Ractors.make_shareable(_attr_readonly | attributes) # Pass the new attributes down to subclasses that hold their own copy. descendants.each do |subclass| next if subclass._attr_readonly.equal?(subclass.superclass._attr_readonly) subclass._attr_readonly = ActiveSupport::Ractors.make_shareable(subclass._attr_readonly | attributes) end if ActiveRecord._raise_on_assign_to_attr_readonly # The code generator changed, also for subclasses that already # generated their own writers. undefine_attribute_methods descendants.each(&:undefine_attribute_methods) include(HasReadonlyAttributes) end end
#define_method_attribute=(canonical_name, owner:, as: canonical_name) (private)
[ GitHub ]# File 'activerecord/lib/active_record/readonly_attributes.rb', line 62
def define_method_attribute=(canonical_name, owner:, as: canonical_name) if ActiveRecord._raise_on_assign_to_attr_readonly && readonly_attribute?(canonical_name) ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method( canonical_name, writer: true, ) do |temp_method_name, attr_name_expr| owner.define_cached_method(temp_method_name, as: "#{as}=", namespace: :active_record_readonly) do |batch| batch << "def #{temp_method_name}(value)" << " unless new_record?" << " raise ActiveRecord::ReadonlyAttributeError.new(#{attr_name_expr})" << " end" << " @attributes.write_from_user(#{attr_name_expr}, value)" << "end" end end else super end end
#readonly_attribute?(name) ⇒ Boolean
This method is for internal use only.
# File 'activerecord/lib/active_record/readonly_attributes.rb', line 57
def readonly_attribute?(name) # :nodoc: _attr_readonly.include?(name) end
#readonly_attributes
Returns an array of all the attributes that have been specified as readonly.
# File 'activerecord/lib/active_record/readonly_attributes.rb', line 53
def readonly_attributes _attr_readonly end