2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ActiveRecordのscopeをインスタンスに対しても使いたい

Last updated at Posted at 2017-12-20
1 / 9

渋谷.rb[:20171220]の相談LTネタです。


kaiba

  • 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

商品は表示だけはしたい

image.png


こうしたいけど怒られる

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条件が得れれるのでそこをみて頑張ってやることもできる(黒魔術)
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?