Reputation: 6399
According to this question and the documentation of attr_readonly
the following should be possible:
class MyModel < ActiveRecord::Base
attr_accessible :foo
attr_readonly :bar
end
m = MyModel.create(foo: '123', bar: 'bar') # Should work
m.update_attributes(bar: 'baz') # Should not work
However the first one fails, saying that I can't mass-assign bar
. What am I mising?
Upvotes: 6
Views: 2170
Reputation: 1738
Before Rails 7.1 attr_accessible
prevented the change from being persisted on the database, but it allowed the change to be made and kept in memory:
class Dashboard < ApplicationRecord
attr_readonly :name
end
d = Dashboard.create(name: "INITIAL NAME")
d.update(name: "ANOTHER NAME")
d.name #=> "ANOTHER NAME"
d.reload && d.name #=> "INITIAL NAME"
Since Rails 7.1 an error will be raised if we try to update a persisted readonly attributed. (However please check your app configuration active_record.raise_on_assign_to_attr_readonly
)
Upvotes: 0
Reputation: 370
You can make the attribute , suppose ,key as:-
attr_accessible :key
and then add one more validation
validate :check_if_key_changed, :on=> :update
private
def check_if_key_changed
if self.key_changed?
errors.add(:key,"cant change key")
end
end
In this way you will be able to mass-assign it once on creation and can also make sure that it do not get updated.
Upvotes: 2
Reputation: 21791
From documentation
attr_accessible
takes a list of attributes that will be accessible. All other attributes will be protected.
So attr_accessible
made bar
attribute as protected from mass-assignment.
Upvotes: 4