Question: I wish to validate attribute `amount`. The allowed amount differ per admin user role. So need to update (or not) based on role of the admin who updates the funds, not the user who the funds belong to.

```
  class UserFund
    validate :validate_amount

      def validate_amount
        if current_user.admin?
          amount <= 100
        elsif current_user.cs?
          amount <= 25
        elsif current_user.staff?
          amount <= 15
        end
      end
    end

```

`User has_many :user_funds`
`UserFund belongs_to :user`
BUT
current\_user != user.
the user who edits funds (current\_user) is admin, not the user who the funds belong to.

But you should not use `current_user` in the model I think. What would be the best practice to solve this?

Answer: 
If `current_user` has no relations to `UserFund` object which is going to be saved, then I think it would be better to transform validator into a separate method. And since that method implies some knowledge about `User` class, it would make sense to move it to `User` class as an instance method (or if admin and user are different, then to admin class):

```
class User < ApplicationRecord
  def amount_too_big?(amount)
    return admin? && amount > 100 || cs? && amount > 25 || staff? && amount > 15
  end
end

```

and call this method in the controller before saving `UserFund` object:

```
if current_user.amount_too_big?(amount)
  # Render error message about unacceptably big funds 
  return
end

```

Why so? Very likely `current_user` object is defined by some controller filter, so it's available in controllers and views only. And `UserFund` object has access only to `User` model funds belong to. Giving access to `current_user` from `UserFund` is possible only by calling some other method and passing `current_user` as an argument, which is not accepted on validation.

Other point: when running from rails console, `current_user` is not defined. `UserFund` object will have no idea what `current_user` is, so could not use it at all.
I think this is a good case for the "context" on validations <https://guides.rubyonrails.org/active_record_validations.html#on>

You can define different validations on different contexts (ie: different roles).

```
validate :admin_amount, on: :admin
validate :cs_amount, on: :cs
validate :staff_amount, on: :staff

def admin_amount
  errors.add(:amount, 'is too long') if amount > 100
end

def cs_amount
  errors.add(:amount, 'is too long') if amount > 25
end

def staff_amount
  errors.add(:amount, 'is too long') if amount > 15
end
#of course, you can DRY this a lot, i'm just repeating a lot of code to make it clearer

```

Now you can save a record (or check if is valid) using a "context" key.

```
fund = UserFund.new
fund.save(context: current_user.role.to_sym) #assuming the role is a string
# of fund.valid?(context: current_user.role.to_sym)

```