Ruby's Safe Navigation Operator – Using Safe Navigation in in a Rails App with Pundit



Ruby's Safe Navigation Operator – Using Safe Navigation in in a Rails App with Pundit

0 0


safe-navigation-presentation

Presentation of the new Ruby 2.3 safe navigation operator

On Github pareidoliax / safe-navigation-presentation

Ruby's Safe Navigation Operator

Using Safe Navigation in in a Rails App with Pundit

Created by Xander Miller / @pareidoliax

Safe Navigation

New to Ruby 2.3

Shorthand for a common pattern

Similar to Rails try(:method)

Might be confused with &block

Shorthand for Conditional AND

Often to avoid a no method exception we use this pattern

  current_user && current_user.name

The safe navigation operator shortens this to one operation

  current_user&.name

Similar to Rails .try(:method)

Safe Navigation passes forward nil while the Rails try(:method) catches any exception thrown by the method call.

This returns nil with .try()

  42.try(:first)

but throws a no method exception when using safe navigation

  42&.first

This makes safe naviagation useful for situations in Rails where you just want to handle the possiblity of a nil object.

Not to be confused with &block

Safe Navigator operator makes sense but could be confused with the way Ruby handles named blocks

  def speak(&block)
    puts block.call
  end

or

  [1, 1, 1].map(& :to_s)

This makes safe naviagation useful for situations in Rails where you just want to handle the possiblity of a nil object.

Pundit Policy file

class ContactPolicy < ApplicationPolicy

  def show?
    user.present? && [:admin, :manager, :support, :customer].include?(user.role)
  end

  def new?
    show?
  end

  def create?
    new?
  end

  def edit?
    user.present? && [:admin, :manager, :support].include?(user.role)
  end

  def update?
    show?
  end

  def delete?
    user.present? && [:admin].include?(user.role)
  end

end

Policy with Safe Navigation Operator

  def edit?
    user.present? && [:admin, :manager, :support].include?(user.role)
  end

becomes

  def edit?
    [:admin, :manager, :support].include?(user&.role)
  end
Ruby's Safe Navigation Operator Using Safe Navigation in in a Rails App with Pundit Created by Xander Miller / @pareidoliax