Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
TED_modeki_共創ラボ_20251203.pdf
iotcomjpadmin
0
120
[2025-12-12]あの日僕が見た胡蝶の夢 〜人の夢は終わらねェ AIによるパフォーマンスチューニングのすゝめ〜
tosite
0
120
Snowflake導入から1年、LayerXのデータ活用の現在 / One Year into Snowflake: How LayerX Uses Data Today
civitaspo
0
2.1k
[Data & AI Summit '25 Fall] AIでデータ活用を進化させる!Google Cloudで作るデータ活用の未来
kirimaru
0
260
2025-12-18_AI駆動開発推進プロジェクト運営について / AIDD-Promotion project management
yayoi_dd
0
150
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
Connection-based OAuthから学ぶOAuth for AI Agents
flatt_security
0
270
接客歴・営業歴の方が長いエンジニアから見たre:Invent2025
yama3133
0
100
MariaDB Connector/C のcaching_sha2_passwordプラグインの仕様について
boro1234
0
1k
1人1サービス開発しているチームでのClaudeCodeの使い方
noayaoshiro
2
560
「もしもデータ基盤開発で『強くてニューゲーム』ができたなら今の僕はどんなデータ基盤を作っただろう」
aeonpeople
0
200
Amazon Connect アップデート! AIエージェントにMCPツールを設定してみた!
ysuzuki
0
120
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
54
7.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Embracing the Ebb and Flow
colly
88
4.9k
The Pragmatic Product Professional
lauravandoore
37
7.1k
Reality Check: Gamification 10 Years Later
codingconduct
0
1.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Raft: Consensus for Rubyists
vanstee
141
7.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
15
So, you think you're a good person
axbom
PRO
0
1.8k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
400
Deep Space Network (abreviated)
tonyrice
0
20
Context Engineering - Making Every Token Count
addyosmani
9
540
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