본문 바로가기

소프트웨어-이야기/프로그래밍 언어와 프레임워크

레일즈에 Service/Decorator Layer 적용하기 (4) - Service Object

이 포스팅은 Build Sleek Rails Components With Plain Old Ruby Objects을 정리한 글입니다 :)



Query Object


1.Query Object은 데이터 쿼리를 나타내는 PORO입니다. 이 객체는 같은 쿼리 로직을 애플리케이션의 여러 장소에서 사용할 수 있도록 해주는 역할을 합니다.그리고 유닛테스트를 더 독립적으로 만들어주기도 합니다. 

2. Query Object를 사용하면, 복잡한 SQL 문들을 자체 클래스로 추출해낼 수 있습니다.

3. Query Object는 표준과 비즈니스 로직을 기반으로 된 데이터를 반환합니다. 



이전에 설명했던 예시 코드에는 복잡한 쿼리가 없어서, Query Object가 크게 효율적이진 않습니다. 하지만 예시를 들기 위해서, Report::Generate#call에 있는 쿼리를 genetate_entries_query.rb으로 추출해보겠습니다. 



이렇게 되면 call 함수는 아래처럼 변경됩니다. 


def
call @user.entries.group_by(&:week).map do |week, entries| WeeklyReport.new( ... ) end end


  def call
    weekly_grouped_entries = GroupEntriesQuery.new(@user).call


    weekly_grouped_entries.map do |week, entries|
      WeeklyReport.new(
       ...
      )
    end
  end

Query Object은 Plain Old Ruby Class여서, 쿼리를 실행하는 책임만 가집니다.


Entry를 만드는 Service Object 만들기

 def create
    begin
      CreateEntry.new(current_user, entry_params).call
      flash[:notice] = 'Entry was successfully created.'
    rescue Exception => e
      flash[:error] = e.message
    end

    redirect_to root_path
  end