lucas clemente
lucas clemente

Reputation: 6399

Rails attr_readonly doesn't work

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

Answers (3)

Francesco Mari
Francesco Mari

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

Nikita Singh
Nikita Singh

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

megas
megas

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

Related Questions