What if you could speak directly to your database and get exactly what you want, no limits?
Why Raw SQL when needed in Ruby on Rails? - Purpose & Use Cases
Imagine you need to get a complex report from your database, but your usual Rails queries just can't express it easily.
Trying to build this report with only Rails query methods can be slow, confusing, and sometimes impossible, leading to messy code and poor performance.
Using raw SQL lets you write exactly the database commands you need, making complex queries clear, fast, and reliable.
User.where("age > ?", 30).joins(:orders).group('users.id').having('count(orders.id) > 5')
ActiveRecord::Base.connection.execute("SELECT users.*, COUNT(orders.id) FROM users JOIN orders ON orders.user_id = users.id WHERE users.age > 30 GROUP BY users.id HAVING COUNT(orders.id) > 5")You can unlock powerful database features and optimize performance beyond what Rails queries allow.
A sales dashboard needing a fast summary of customers with many orders in the last month, using a complex SQL query for speed.
Rails queries are great but sometimes limited.
Raw SQL gives you full control for complex needs.
It helps write faster, clearer, and more powerful database commands.
Practice
Solution
Step 1: Understand Rails helpers limitations
Rails helpers cover many common queries but sometimes complex queries need direct SQL.Step 2: Identify why raw SQL is used
Raw SQL is used when Rails helpers cannot express the needed query efficiently or at all.Final Answer:
To write database queries that Rails helpers cannot easily express -> Option AQuick Check:
Raw SQL = complex queries [OK]
- Thinking raw SQL replaces ActiveRecord entirely
- Believing raw SQL speeds up server startup
- Confusing raw SQL with migration generation
Solution
Step 1: Identify method for raw SELECT returning models
Rails providesfind_by_sqlto run raw SELECT queries returning model instances.Step 2: Differentiate from execute method
connection.executeruns SQL but returns raw results, not model objects.Final Answer:
Model.find_by_sql(sql_query) -> Option BQuick Check:
Raw SELECT with models = find_by_sql [OK]
- Using connection.execute for SELECT expecting models
- Confusing where with raw SQL execution
- Assuming raw_query is a valid method
users = User.find_by_sql("SELECT * FROM users WHERE age > 30")
puts users.first.nameWhat will this code do?
Solution
Step 1: Understand find_by_sql behavior
find_by_sql runs the raw SELECT and returns model objects matching the query.Step 2: Analyze the query and output
The query selects users with age > 30, andusers.first.nameprints the first matching user's name.Final Answer:
Print the name of the first user older than 30 -> Option DQuick Check:
find_by_sql returns models = prints first name [OK]
- Expecting raw SQL to return only IDs
- Thinking it raises syntax error without reason
- Confusing output with count instead of first record
result = ActiveRecord::Base.connection.execute("SELECT * FROM users WHERE name = 'Alice'")
puts result.nameSolution
Step 1: Understand connection.execute return type
connection.execute returns a raw database result, not model objects.Step 2: Identify why .name fails
Raw result sets do not have model attributes like .name; you must extract data manually.Final Answer:
The result is a raw result set, not a model, so .name is undefined -> Option AQuick Check:
connection.execute returns raw results, no model methods [OK]
- Assuming execute returns model objects
- Thinking SQL syntax is wrong
- Believing connection is inaccessible
Solution
Step 1: Identify method for non-SELECT raw SQL
For UPDATE queries, useconnection.executeto run raw SQL commands.Step 2: Check each option's correctness
ActiveRecord::Base.connection.execute("UPDATE users SET status = 'active'") uses connection.execute with UPDATE SQL correctly. User.find_by_sql("UPDATE users SET status = 'active'") misuses find_by_sql which is for SELECT. User.where("status = 'active'").update_all uses ActiveRecord but not raw SQL. User.connection.execute("SELECT * FROM users WHERE status = 'active'") runs SELECT, not UPDATE.Final Answer:
ActiveRecord::Base.connection.execute("UPDATE users SET status = 'active'") -> Option CQuick Check:
Raw UPDATE = connection.execute [OK]
- Using find_by_sql for UPDATE queries
- Confusing ActiveRecord methods with raw SQL
- Running SELECT instead of UPDATE
Ready to prove it?
Pass the test and this pattern moves unknown
