ActiveRecord의 scope를 인스턴스에 대해서도 사용하고 싶다

4069 단어 RailsActiveRecord

시부야.rb[:20171220]의 상담 LT 재료입니다.





카이바


  • twitter @ kaiba
  • 일본술에 집착이 있다
  • 실수로 회식을 넣어 버렸기 때문에 LT만 하면 나옵니다…


  • 이런 상품 모델, 이런 scope가 있었다고 한다


    class Item < ActiveRecord::Base
      scope :buyable, (-> {
        where(safety: true)
        .where(ero: false)
        .where(grotesque: false)
        .where(has_copyright: true)
        .where(deleted_at: nil)
      })
    end
    

    상품은 표시만 하고 싶다





    그런데 화가 난다.


    class ItemsController < ApplicationController
      def show
        @item = Item.find_by(id: p[:id])
        if @item.buyable?
          # ...
    

    힘들다


    class Item < ActiveRecord::Base
      def buyable?
        safety && !ero && !grotesque? && 
          has_copyright? && deleted_at.blank? 
      end
    end
    

    그렇지 않고 SQL이 발행됩니다.


    class Item < ActiveRecord::Base
      def buyable?
        Item.buyable.where(id: id).present?    
      end
    end
    

    여기에 여러분으로부터 받은 조언을 쓴다


  • Item.buyable.where(id: id).present?에서 자신을 찾아 버리는 것도 있지만, N + 1 문제와 캐시를 생각하고 사용해야합니다
  • rails에는 추상화 된 조건이 없으므로 조건을 최선을 다하고 추상화합니다.
  • Item.buyable.values 를 보면 WhereClauses 에서 where 조건을 얻을 수 있으므로 거기를 보고 열심히 할 수도 있다(흑마술)
  • 좋은 웹페이지 즐겨찾기