> For the complete documentation index, see [llms.txt](https://simian114.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simian114.gitbook.io/blog/undefined/rubyonrails/undefined-7/validation-1/validator.md).

# validator 클래스

{% hint style="info" %}
[**RAILS GUILDE**](https://guides.rubyonrails.org/active_record_validations.html#validates-with)

[**STACKOVERFLOW - validator 파일 위치 1**](https://stackoverflow.com/questions/5263239/where-should-rails-3-custom-validators-be-stored)

[**STACKOVERFLOW - validator 파일 위치2**](https://stackoverflow.com/questions/42253003/where-should-i-put-the-custom-validators-in-rails-5)

[**RAILS API**](https://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html)
{% endhint %}

## 상황

모델에 `validation` 을 작성해주다보면, **기본으로 제공하는 옵션으로 유효성 체크를 하지 못하는 경우가 발생한다.**

이 경우 보통 `validate` 를 사용해서 `custom` 메서드를 만들어서 사용한다. 하지만 이것도 유효성 관련 체크가 너무 길어져서 `model.rb` 파일 자체가 엉망이 되는 경우가 있다.

이럴때는 `validation` 체크를 **`model.rb` 가 아닌 다른 파일에서 해줄주는 없을까?**

## 해결

### validator 클래스를 만들자

[**공식 가이드 페이지**](https://guides.rubyonrails.org/active_record_validations.html#validates-with) 를 보면 자세히 알 수 있다. 우리 코드에서는 `iwoo` 님이 작성한 `tournament` 관련 파일에서 확인할 수 있다.

`validator` 를 사용하기 위해서는 아래와 같은 순서를 따르면 된다.

`validator` 을 작성한다.

* 이 때 `validator` 을 어디에 작성할지 결정해야한다. `model.rb` 또는 다른 파일. 일단 나같은 경우는 `model.rb` 에 너무 많은 커스텀 `validation` 이 들어가서 문제라고 생각했기 때문에 `model.rb` 아닌 다른 파일에 작성해야하는 상황. 이 문제는 아래 링크들을 보고 해결하면 된다.
* [**stackoverflow1**](https://stackoverflow.com/questions/5263239/where-should-rails-3-custom-validators-be-stored)
* [**stackoverflow2**](https://stackoverflow.com/questions/42253003/where-should-i-put-the-custom-validators-in-rails-5)
* 결론은 `validator` 클래스의 정해진 위치는 없지만, `app` 폴더에 `validators` 폴더를 만들고 이 안에 **이름규칙**을 지킨 `validator` 을 만들면 된다. 또한 여기에 만들면 레일즈에서 자동으로 **auto load** 을 해주기 때문에 따로 처리할 일은 없다.

```ruby
# /app/validators/tournament_validator.rb .. 이름 규칙은 다른 파일들처럼 스네이크

class TournamentValidator < ActiveModel::Validator
  def validate(record)
    if record.start_date.nil? || 
        record.start_date.to_date <= Date.current ||
        invalid_tournament_time?(record.tournament_time)
      record.errors.add :base, message: "토너먼트 생성은 내일 이후의 일정으로만 생성 가능합니다."
    end
  end

  def invalid_tournament_time?(tournament_time)
    playble_time = 9..22
    !playble_time.include?(tournament_time.hour)
  end
end
```

`model.rb` 에서 아래처럼 해주면된다!&#x20;

여기서 핵심은 ***validates\_with*** 를 사용한다는 것!!!

```ruby
class Tournament < ApplicationRecord
    ...
  ...
  validates_with TournamentValidator, field: [ :start_date, :tournament_time]
end
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://simian114.gitbook.io/blog/undefined/rubyonrails/undefined-7/validation-1/validator.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
