default scopeの被害報告
TRANSCRIPT
![Page 1: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/1.jpg)
default_scope の 被害報告
2015/03/28 minami.rb 最初で最後のLT大会
無量井 健(@muryoimpl)
https://www.flickr.com/photos/jakerust/16827350035
![Page 2: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/2.jpg)
自己紹介
• 無量井 健(むりょうい けん)
• 永和システムマネジメント 7ヶ月目
• Ruby関西, 関西Ruby会議04・05, るびま etc
• 休日は、低機動型寝たきり二時間サスペンス廃人
![Page 3: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/3.jpg)
皆さんご存知だと おもいますが
https://www.flickr.com/photos/aruarian/2626408619
![Page 4: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/4.jpg)
https://www.flickr.com/photos/aruarian/2626408619
default_scope
![Page 5: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/5.jpg)
default_scopeclass Item < ActiveRecord::Base default_scope -> { order(:order_no) } end
irb(main)> Item.find(1) SELECT "items".* FROM “items" WHERE "items"."id" = ? ORDER BY “items"."order_no" DESC LIMIT 1 [["id", 1]]
https://www.flickr.com/photos/lintmachine/3652702115
![Page 6: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/6.jpg)
何もしなくても 勝手に
条件がつきますねhttps://www.flickr.com/photos/aruarian/2626408619
![Page 7: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/7.jpg)
便利ですね
https://www.flickr.com/photos/aruarian/2626408619
![Page 8: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/8.jpg)
default_scope の条件外す方法 ありますね
https://www.flickr.com/photos/aruarian/2626408619
![Page 9: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/9.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
unscopedirb(main)> Item.unscoped.find(1) SELECT "items".* FROM “items" WHERE "items"."id" = ? DESC LIMIT 1 [["id", 1]]
irb(main)> Item.unscoped { Item.find(1) } SELECT "items".* FROM “items" WHERE "items"."id" = ? LIMIT 1 [["id", 1]]
![Page 10: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/10.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
exceptirb(main)> Item.except(:order).find(1) SELECT "items".* FROM “items" WHERE "items"."id" = ? DESC LIMIT 1 [["id", 1]]
![Page 11: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/11.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
unscopeirb(main)> Item.unscope(:order).find(1) SELECT "items".* FROM “items" WHERE "items"."id" = ? DESC LIMIT 1 [["id", 1]]
![Page 12: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/12.jpg)
外れましたね?
https://www.flickr.com/photos/aruarian/2626408619
![Page 13: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/13.jpg)
調べると だいたいこういう例が
載っていますhttps://www.flickr.com/photos/aruarian/2626408619
![Page 14: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/14.jpg)
さてhttps://www.flickr.com/photos/aruarian/2626408619
![Page 15: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/15.jpg)
結合とかしてたら どうですかね?
https://www.flickr.com/photos/aruarian/2626408619
![Page 16: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/16.jpg)
includesしてみるぞ
class Author < ActiveRecord::Base has_many :posts
default_scope -> { where(status: :ok) } end
class Post < ActiveRecord::Base belongs_to :author end
https://www.flickr.com/photos/lintmachine/3652702115
![Page 17: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/17.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
includesしてみるぞirb(main)> Post.includes(:author) .where(status: :ok) .where(authors: {name: ‘a’}) SELECT "posts"."id" AS t0_r0, … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = “posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 18: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/18.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
unscopedirb(main)> Author.unscoped { Post.includes(:author) .where(status: :ok) .where(authors: {name: ‘a’}) } SELECT "posts"."id" AS t0_r0, … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = “posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 19: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/19.jpg)
外れない!https://www.flickr.com/photos/aruarian/2626408619
![Page 20: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/20.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
exceptirb(main)> Post.includes(:author).except(:where) .where(status: :ok) .where(authors: {name: ‘a’}) SELECT "posts"."id" AS t0_r0, … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = “posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 21: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/21.jpg)
そもそも ON句だし…
https://www.flickr.com/photos/aruarian/2626408619
![Page 22: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/22.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
exceptirb(main)> Post.includes(:author) .except(on: :status) #ないよね…無視される .where(status: :ok) .where(authors: {name: ‘a’}) SELECT "posts"."id" AS t0_r0, … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = “posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 23: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/23.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
unscopeirb(main)> Post.includes(:author) .unscope(on: :status) #ないよね… .where(status: :ok) .where(authors: {name: ‘a’})
ArgumentError: Hash arguments in .unscope(*args) must have :where as the key.
![Page 24: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/24.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
unscopeirb(main)> Post.includes(:author) .unscope(where: :status) .where(status: :ok) .where(authors: {name: ‘a’}) SELECT "posts"."id" AS t0_r0 … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 25: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/25.jpg)
別の関連つくって…class Author < ActiveRecord::Base has_many :posts
default_scope -> { where(status: :ok) } end
class Post < ActiveRecord::Base belongs_to :author belongs_to :unscoped_author, -> { unscope(where: :status) }, foreign_key: :author_id, class_name: ‘Author’ end https://www.flickr.com/photos/lintmachine/3652702115
![Page 26: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/26.jpg)
https://www.flickr.com/photos/lintmachine/3652702115
別の関連つくって…irb(main)> Post.includes(:unscoped_author) .where(status: :ok) .where(authors: {name: ‘a’}) SELECT "posts"."id" AS t0_r0, … FROM "posts" LEFT OUTER JOIN "authors" ON "authors"."id" = “posts"."author_id" AND "authors"."status" = ? WHERE "authors"."name" = ? [["status", 1], ["name", "a"]]
![Page 27: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/27.jpg)
やはり 外れない!
https://www.flickr.com/photos/aruarian/2626408619
![Page 28: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/28.jpg)
https://www.flickr.com/photos/alvarez-tostado/363243449
マ”マ”ーーー
![Page 29: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/29.jpg)
https://www.flickr.com/photos/alvarez-tostado/363243449
ということで…
![Page 30: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/30.jpg)
https://www.flickr.com/photos/alvarez-tostado/363243449
泣きながら こうした…
![Page 31: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/31.jpg)
default_scopes =[]class Author < ActiveRecord::Base has_many :posts
default_scope -> { where(status: :ok) } end
class UnscopedAuthor < Author # ↓ここがポイント self.default_scopes = [] end
class Post < ActiveRecord::Base belongs_to :author belongs_to :unscoped_author, foreign_key :author_id end https://www.flickr.com/photos/lintmachine/3652702115
![Page 32: Default scopeの被害報告](https://reader033.vdocuments.site/reader033/viewer/2022042602/55a5d02d1a28abd4298b476f/html5/thumbnails/32.jpg)
default_scopeさん…• こんな罠がありました… • 単一モデルしか検索しない間は便利さしか感じないかもしれませんが…SQL的にJOINすることになると面倒なことになります(なりました)
• 少し面倒なクエリを考えるときに直面するのですよ…この問題
• 後悔しないように、scopeを毎回つけるか設計を見直すほうが良いと思います
https://www.flickr.com/photos/71508688@N00/5139944772