harinsa
harinsa

Reputation: 3196

Rails make record readonly after update attribute

My model has a attribute void. If void is true, I want the record to be readonly. I tried:

def readonly?
  self.void
end

but this would disable me from saving the record because void is already true before I saved it. Saving a record with void=true would raise ActiveRecord::ReadOnlyRecord exception. So I could never actually store void=true in the database.

How can I make the record readonly after I have save void=true

Upvotes: 1

Views: 1808

Answers (4)

Goko Gorgiovski
Goko Gorgiovski

Reputation: 1462

I have another variant:

  def readonly?
    !persisted? || void_changed? ? false : void
  end

Its means every time when you change void record is not readonly in other cases readlonly? depends from void

Upvotes: 0

harinsa
harinsa

Reputation: 3196

I have found a way to do this without adding any variables, however, the resulting behavior is a bit different.

def readonly?
  begin
    prev = self.class.find(self.id)
    prev.void && self.void
  rescue ActiveRecord::RecordNotFound
    false
  end
end

With this method, the record will correctly be marked readonly, but modifying its attributes is allowed, you will just not be able to save it. Conversely, if you manually return true from readonly? method, then a ReadOnlyRecord would be raise (which I think is preferable). It would be great if anyone can explain why.

Upvotes: 0

Oleh  Sobchuk
Oleh Sobchuk

Reputation: 3722

def readonly?
  persisted? && void
end

EDIT

it will working just for new records.

if you need use for persisted records you can do it in next way:

in your model:

attr_accessor :editable

def readonly?
  editable || !void ? false : true
end

Upvotes: 1

Thong Kuah
Thong Kuah

Reputation: 3283

You can try checking if there's been changes to the void attribute ?

E.g.

def readonly?
  !void_just_changed? && void
end

def void_just_changed?
  void_was.blank? && void?
end

You can modify void_just_changed? to whatever suits you, e.g allow void to be set back to false.

Upvotes: 0

Related Questions