Read more

Consul: Querying a power that might be nil

Henning Koch
January 29, 2013Software engineer at makandra GmbH

Consul Show archive.org snapshot 0.6.1+ gives your Power class a number of static methods that behave neutrally in case Power.current is nil. This allows you to create authorization-aware models that still work when there is no user at the end of a web browser, e.g. on the console, during tests or during batch processes.


Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

You will often want to access Power.current from another model, to e.g. iterate through the list of accessible users:

class UserReport

  def data
    Power.current.users.collect do |user|
      [user.name, user.email, user.income]
    end
  end

end

Good practice is for your model to not crash when Power.current is nil. This is the case when your model isn't
called as part of processing a browser request, e.g. on the console, during tests and during batch processes.
In such cases your model should simply skip authorization and assume that all users are accessible:

class UserReport

  def data
    accessible_users = Power.current.present? Power.current.users || User
    accessible_users.collect do |user|
      [user.name, user.email, user.income]
    end
  end

end

Because this pattern is so common, the Power class comes with a number of class methods you can use to either query
Power.current or, if it is not set, just assume that everything is accessible:

class UserReport

  def data
    Power.for_model(user).collect do |user|
      [user.name, user.email, user.income]
    end
  end

end

There is a long selection of class methods that behave neutrally in case Power.current is nil:

Call Equivalent
Power.for_model(Note) Power.current.present? ? Power.current.notes : Note
Power.for_model(:updatable, Note) Power.current.present? ? Power.current.updatable_notes : Note
Power.include_model?(Note) Power.current.present? ? Power.notes? : true
Power.include_model?(:updatable, Note) Power.current.present? ? Power.updatable_notes? : true
Power.include_model!(Note) Power.notes! if Power.current.present?
Power.include_model!(:updatable, Note) Power.updatable_notes! if Power.current.present?
Power.for_record(Note.last) Power.current.present? ? Power.current.notes : Note
Power.for_record(:updatable, Note.last) Power.current.present? ? Power.current.updatable_notes : Note
Power.include_record?(Note.last) Power.current.present? ? Power.note?(Note.last) : true
Power.include_record?(:updatable, Note.last) Power.current.present? ? Power.updatable_note?(Note.last?) : true
Power.include_record!(Note.last) Power.note!(Note.last) if Power.current.present?
Power.include_record!(:updatable, Note.last) Power.updatable_note!(Note.last) if Power.current.present?
Henning Koch
January 29, 2013Software engineer at makandra GmbH
Posted by Henning Koch to makandra dev (2013-01-29 15:10)