Search code examples
ruby-on-railsrubyvalidationruby-on-rails-4custom-validators

How to implement custom validations for methods called by other methods?


I create a Subscription for a User via the method .create_subscription(plan_title).

That method checks that it's possible to subscribe (not oversubscribed plan or archived subscription) via the method .plan_subscribable?(plan).

This method does either return true or false, but I would like it to return an error message as well that could be passed to the user if false.

How and where do I implement these validation errors?

class User

  def plan_subscribable?(plan)
    users_subscribed = Subscription.where(plan_id: plan.id).size

    return false unless users_subscribed <= plan.quantity
    return false unless plan.archived == false
    return true
  end

  def create_subscription(plan_title)
    plan = Plan.where(title: plan_title).first

    if plan_subscribable?(plan)
      Subscription.create(...)
    end
  end

end

Solution

  • You could modify plan_subscribable? to return a boolean true or a string containing the specific error message:

    def plan_subscribable?(plan)
      return 'The number of users cannot be higher than the plan quantity' unless users_subscribed <= plan.quantity
      return 'Archived plans are not subscribable' unless plan.archived == false
      return true
    end
    

    Then, evaluate whether the returned value from plan_subscribable? is true. If it is not, the statement is implicitly false and you can use the returned value as the error message:

    def create_subscription(plan_title)
      plan = Plan.where(title: plan_title).first
    
      subscribable_or_error = plan_subscribable?(plan)
      if subscribable_or_error === true
        Subscription.create(...)
      else
        error_message = subscribable_or_error
      end
    end