Question

I'd like to know if there's a way to define the proc at the top of this method elsewhere and still retain the proc's ability to return from the scope of a method.

  def add_user_to_team(user_id, team_id)

    v = Proc.new do |t|
      return t if t.error
      t
    end

    User.transaction do

      user = v.call(
        validate_user_exists(user_id)).obj

      team = v.call(
        validate_team_exists(team_id)).obj

      ...lots of other validations...

      result(true, nil, team_user)
    end

  end

I'd like to be able to define this proc in a module that we could include elsewhere. But, when I have a method return the proc, i get a LocalJumpError with the return statement.

For example, I'd like to do

def validate
  Proc.new do |t|
    return t if t.error
    t
  end
end

And refine the the original code to do

  def add_user_to_team(user_id, team_id)

    User.transaction do

      user = validate.call(
        validate_user_exists(user_id)).obj

      team = validate.call(
        validate_team_exists(team_id)).obj

      ...lots of other validations...

      result(true, nil, team_user)
    end

  end

I'm also open to any other suggestions for how to consolidate this error-checking logic which

  1. bails out if the scoped method if a validation fails
  2. returns the object if no error and continues
Was it helpful?

Solution

One possibility is to use throw/catch to prematurely exit the method:

module ValidationHelpers
  def check t
    throw :fail, t if t.error
    t
  end
end

And to use it in your validation method:

def add_user_to_team(user_id, team_id)
  catch(:fail) do
    User.transaction do
      user = check(validate_user_exists(user_id)).obj
      team = check(validate_team_exists(team_id)).obj
      # ...lots of other validations...
      result(true, nil, team_user)
    end
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top