views:

108

answers:

3

I have an interactive Ruby on Rails application which I would like to put into a "read only mode" during certain times. This will allow users to read the data they need but block them from actions that write to the database.

One way to do this would be to have a true/false variable located in the database that was checked before any write was made.

My question. Is there a more elegant solution for this problem out there?

+3  A: 

Permissions plugin? Something simple like cancan where you define what a user can do, when. It will allow you to display links, or not, and restrict access to controller actions. The railscast will explain better than I can.

http://github.com/ryanb/cancan

http://railscasts.com/episodes/192-authorization-with-cancan

mark
+3  A: 

Another good one which I liked a little better is Declarative Authorization which is covered by Railscasts as well: Railscasts - Declarative Authorization

nuclearsandwich
A: 

If you really want to prevent any database write, the easiest way I can imagine would be to override the readonly? method of a model to always return true, either in selected models or maybe even for all ActiveRecord models. If a model is set to readonly (normally done by calling #readonly! on it), any try to save the record will raise an ActiveRecord::ReadOnlyRecord error.

module ActiveRecord
  class Base
    def readonly?
      true
    end
  end
end

(actually untested code, but you get the idea…)

Andreas
This is potentially an interesting solution. How would I toggle readonly mode on and off on the fly for a specific model?
Nicolo77
By monkeypatching ActiveRecord::Base, it'll affect all models (I thought that's what you were looking for). You could write some fancy conditions that check the actual class, like `def readonly?; self.class === MyProtectedClass ? true : super; end`, but that can quickly end up in a mess - it's probably cleaner to directly override the readonly? method in every model class you want to modify.
Andreas
Btw, instead of overriding the readonly? method in a model, it is probably more unobtrusive and 'cleaner' to simply add an after_find callback that sets every record to readonly: `def after_find; readonly!; end`
Andreas