본문 바로가기

소프트웨어 이야기/장고와 루비온레일즈

레일즈에 Service/Decorator Layer 적용하기 (5) - Form Object에서 유효성 체크하기

이 위키는 Build Sleek Rails Components With Plain Old Ruby Objects을 정리한 글입니다 :)


저자는 모델 객체에서는 association과 constant만 관리되는게 더 로직을 깔끔하게 만든다고 이야기했었습니다. 그래서 유효성 체크와 callback 로직은 model에서 다루지 않아야한다고 했죠. 

그래서 이번 챕터에서는 model 객체에 있던 유효성 로직을 지우고, 대신에 form object를 사용하도록 하는 방법을 설명하고자 합니다.


Form Object란?

Form Object는 Plain Old Ruby Object입니다. 그리고 이건 데이터베이스를 호출해야할 때, controller와 service Object에서 사용되는 객체입니다.


Form Object를 언제 / 왜 사용해야하나요?

Form Object는 아래와 같은 경우에 유용하게 사용될 수 있습니다.


1. 레일즈 모델의 validation 로직을 빼내고 싶을 때

2. 하나의 폼에서 여러 모델을 수정해줘야 할 때


Form Object는 하나의 폼에 보여져야하는 필드들을 attribute으로 관리하고 있습니다. 그리고 유효성 체크 로직도 이 클래스에서 관리하고 있습니다.

그래서 한 폼에서 여러 모델을 다루고 있는 경우, 유용하게 사용될 수 있습니다.

이렇게 사용하면 단일 책임 원칙을 지킬 수 있게 되어서, 좀더 나은 설계를 할 수 있게 도와줍니다 :) 


예를 들어 유저 폼에서 유저 포인트 정보와 유저 정보를 모두 다루고 있으면 복잡해지겠죠! 이 경우, Form Object를 사용하면, 로직을 깔끔하게 정리할 수 있을 것 같아요.


어떻게 만들면 되죠?

1. 루비 클래스를 만듭니다

2. ActiveModel::Model을 include 합니다 ( 레일즈 3에서는 Naming, Conversion, Validation을 include 해줘야한다네요. 어떤 건지는 실제로 적용해봐야 알것같아요 )

3. 새로운 폼 클래스를 만들어서 적용해보면 됩니다.

reform이라는 젬을 사용하면, Form Object를 만들기 편합니다 :) 


샘플 코드에 적용해보기

 class CreateEntry
       ......

        def call
          @entry_form = ::EntryForm.new(@params)

          if @entry_form.valid?
             ....
          else
             ....
          end
        end
      end

create entry에서 EntryForm을 사용하도록 변경해주면 됩니다.


참고 자료

active record model을 사용해서 form object를 만드는 방법 - ActiveModel Form Object 

여러 모델을 form에 적용하는 방법 (1) - Saving multiple Models with Form Objects and Transactions 

여러 모델을 form에 적용하는 방법 (2) - Rails Form Object with Virtus: has_many association 스택오버플로우

reform 적용 사례 동영상 - https://www.youtube.com/watch?v=d9vMENoqxEE