Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ActiveRecord Anti-Patterns
Search
Ethan Gunderson
November 04, 2011
Technology
2
310
ActiveRecord Anti-Patterns
Ethan Gunderson
November 04, 2011
Tweet
Share
Other Decks in Technology
See All in Technology
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.2k
AIフル活用で挑む!空間アプリ開発のリアル
taat
0
140
AI AgentをLangflowでサクッと作って、1日働かせてみた!
yano13
1
120
Kubernetes self-healing of your workload
hwchiu
0
360
Wasmの気になる最新情報
askua
0
180
データ戦略部門 紹介資料
sansan33
PRO
1
3.8k
生成AIを安心して活用するために──「情報セキュリティガイドライン」策定とポイント
gree_tech
PRO
0
230
AI駆動で進める依存ライブラリ更新 ─ Vue プロジェクトの品質向上と開発スピード改善の実践録
sayn0
1
110
もう外には出ない。より快適なフルリモート環境を目指して
mottyzzz
11
8.8k
「REALITY」3Dアバターシステムの7年分の拡張の歴史について
gree_tech
PRO
0
120
AI時代におけるデータの重要性 ~データマネジメントの第一歩~
ryoichi_ota
0
710
ソフトウェアエンジニアの生成AI活用と、これから
lycorptech_jp
PRO
0
820
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
697
190k
Building an army of robots
kneath
305
46k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
61k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
jQuery: Nuts, Bolts and Bling
dougneiner
65
7.9k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Writing Fast Ruby
sferik
629
62k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
The Cost Of JavaScript in 2023
addyosmani
55
9.1k
GitHub's CSS Performance
jonrohan
1032
470k
Transcript
Anti-Patterns for fun and profit Active Record Friday, November 4,
2011
Ethan Gunderson @ethangunderson Friday, November 4, 2011
Friday, November 4, 2011
20% 80% Friday, November 4, 2011
Order.all.slice(0, N).select{ |order| order.status == ‘open’} Friday, November 4, 2011
Common Mistakes Friday, November 4, 2011
ActiveRecord Safari Friday, November 4, 2011
“All non-trivial abstractions, to some degree, are leaky.” - Joel
Spolsky Friday, November 4, 2011
Order.all.slice(0, N).select{ |order| order.status == ‘open’} Friday, November 4, 2011
class Order < ActiveRecord::Base scope :open, where(:status => ‘open’) end
Order.open.limit(5) Friday, November 4, 2011
change_table(:users) do |table| table.string :email table.string :status end Migrations Friday,
November 4, 2011
1. Write lock the table. 2. Make a copy of
the table. 3. Make changes to the copy. 4. Promote copy to primary. 5. Repeat 1-4. Friday, November 4, 2011
connection.execute(“ALTER TABLE `users` ADD COLUMN email varchar(255) DEFAULT NULL, ADD
COLUMN status varchar(10) DEFAULT NULL”) Friday, November 4, 2011
change_table(:users, :bulk => true) do |table| table.string :email table.string :status
end Friday, November 4, 2011
The Leaks, they add up. Friday, November 4, 2011
Not Optimizing Queries Friday, November 4, 2011
Order.all.each do |order| #something end Friday, November 4, 2011
Order.all.each do |order| #something end Ouch Friday, November 4, 2011
Iterate over the DB cursor and construct an array of
rows. Initiate an array of ActiveRecord objects. Friday, November 4, 2011
Order.find_each do |order| #something end Friday, November 4, 2011
Order.find_in_batches do |orders| #something end Friday, November 4, 2011
N + 1 Order.all.each do |order| order.user.first_name end Friday, November
4, 2011
N*OMG Order.all.each do |order| order.user.first_name order.user.address.street ... end Friday, November
4, 2011
1 Order.all.includes(:user).each do |order| order.user.first_name end Friday, November 4, 2011
Order.all.includes(:user => :address) each do |order| order.user.first_name order.user.address.street ... end
Friday, November 4, 2011
https://github.com/nesquena/ query_reviewer Friday, November 4, 2011
if Object.const_defined?('ActiveRecord') ActiveRecord::Base.logger = Logger.new (STDOUT) end In your ~/.irbrc...
Friday, November 4, 2011
Race Conditions Friday, November 4, 2011
validates_uniqueness_of Friday, November 4, 2011
Works. Until you hit production. Friday, November 4, 2011
User 1 Checks for uniqueness User 2 Friday, November 4,
2011
User 1 Checks for uniqueness User 2 Checks for uniqueness
Friday, November 4, 2011
User 1 Inserts record User 2 Inserts record Checks for
uniqueness Checks for uniqueness Friday, November 4, 2011
Success! Friday, November 4, 2011
Success! Danger! Friday, November 4, 2011
create_index :users, :email, :unique => true Friday, November 4, 2011
github.com/trptcolin/consistency_fail Friday, November 4, 2011
Abusive Callbacks Friday, November 4, 2011
Loading Associations Friday, November 4, 2011
class Order < ActiveRecord::Base validate :validate_cc_record def validate_cc_record cc.user !=
user end end Friday, November 4, 2011
Take advantage of dirty attributes Friday, November 4, 2011
class Order < ActiveRecord::Base validate :validate_cc_record def validate_cc_record return unless
cc_id.changed? cc.user != user end end Friday, November 4, 2011
class Order < ActiveRecord::Base before_save :update_item_count def update_sold_count item.increment_sold_count(1) end
end Friday, November 4, 2011
This is slow Friday, November 4, 2011
This is *really* hard to debug in a large application.
Friday, November 4, 2011
Order Item Vendor Sales Friday, November 4, 2011
Order Item Vendor Sales Save fails, returns false Friday, November
4, 2011
Order Item Vendor Sales Save fails, returns false Friday, November
4, 2011
Keep callbacks simple. Friday, November 4, 2011
Breaking the Law Friday, November 4, 2011
Demeter Friday, November 4, 2011
Each unit should have only limited knowledge about other units:
only units "closely" related to the current unit. Each unit should only talk to its friends; don't talk to strangers. Only talk to your immediate friends. Friday, November 4, 2011
You can play with yourself. You can play with your
toys. You can play with toys given to you. You can play with toys you’ve made yourself. http://c2.com/cgi/wiki?LawOfDemeter Friday, November 4, 2011
order.user.address Friday, November 4, 2011
But why do I care? Friday, November 4, 2011
Coupling Friday, November 4, 2011
0 25 50 75 100 Coupling Cost of Change Friday,
November 4, 2011
order.user.address Friday, November 4, 2011
class Order < ActiveRecord::Base delegate :address, :to => :user, :prefix
=> true, :allow_nil => true end Friday, November 4, 2011
order.user_address Friday, November 4, 2011
class Order < ActiveRecord::Base def user_address #different implementation end end
Friday, November 4, 2011
Recap Friday, November 4, 2011
Pay attention to the abstraction Friday, November 4, 2011
Optimize those queries Friday, November 4, 2011
Avoid complicated callbacks Friday, November 4, 2011
Itʼs the law. Follow it. Friday, November 4, 2011
The database is your friend. Friday, November 4, 2011
YMMV Friday, November 4, 2011
Thanks! Friday, November 4, 2011