amit_saxena
amit_saxena

Reputation: 7624

How to ignore/supress a specific type of exception (ActiveRecord::ReadOnlyRecord) across my code base

I am trying to create a read only version of my application and have monkey patched ActiveRecord::Base so that it returns true for readonly? across all models:

module ActiveRecord
  class Base
    def readonly?
      true
    end
  end
end 

This results in ActiveRecord::ReadOnlyRecord exceptions being raised wherever I am trying to write to the database. Is there a way to ignore this exception wherever in the code this gets raised and continue with execution of code. Some way to override the exception class, so that it does nothing, i.e. the exception is suppressed.

Upvotes: 1

Views: 535

Answers (3)

Jason Ormes
Jason Ormes

Reputation: 11

You could rescue the exception in your application controller and just ignore it.

Upvotes: 0

wiesion
wiesion

Reputation: 2455

Presuming that

  • All your models inherit from a custom ApplicationRecord
  • You make use of validations
  • All the interfaces accessible through URL to your models don't skip validations
  • You want to use exactly the same source code for your read-only version

i suggest that you work with a global validation, which checks for the presence of an environment variable, let's call it MY_APP_IS_READ_ONLY:

application_record.rb

class ApplicationRecord < ActiveRecord::Base
  # your code ...
  validates :not_read_only_mode
  def not_read_only_mode
    errors.add(:base, "App runs in read-only mode") unless ENV['MY_APP_IS_READ_ONLY'].nil?
  end

Now all of the inherited models should fail the validation and on a failed .save they get redirected to the same URL (depending on your code), never being able to create or update any record. Also by specifying :base as the error source, you create a generic error message which is not tied to any field.

However, if you have models that NEED to be updated (session? user for last login?), you should create a separate class holding this validation and make the conditionally read-only models inherit from it.

Upvotes: 0

Panic
Panic

Reputation: 2405

Instead of making all your models read-only, you can try something like this:

class ApplicationRecord < ActiveRecord::Base
  before_commit do
    raise ActiveRecord::Rollback, 'Read-only'
  end
end

Upvotes: 1

Related Questions