# How to Debug and Inspect the SQL Queries Generated by Ransack

> Learn to debug Ransack SQL queries by calling search.result.to_sql or inspecting the Arel tree with Ransack::Visitor for efficient debugging and query optimization.

- Repository: [ActiveRecord Hackery/ransack](https://github.com/activerecord-hackery/ransack)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Call `search.result.to_sql` on any Ransack search object to view the raw SQL, or inspect the Arel tree directly via `Ransack::Visitor` to debug how predicates are constructed before execution.**

The Ransack gem provides advanced search capabilities for Rails applications by translating HTTP parameters into database queries. When you need to debug and inspect the SQL queries generated by Ransack, you must understand how the library constructs queries through its node-based architecture before handing them off to ActiveRecord. By examining specific source files in the `activerecord-hackery/ransack` repository, you can trace exactly how search parameters become executable SQL.

## Understanding Ransack's Query Building Pipeline

Ransack constructs queries in three distinct phases implemented across core library files. First, `Ransack::Search` in [`lib/ransack/search.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/search.rb) parses input parameters into a tree of nodes including `Ransack::Nodes::Condition`, `Ransack::Nodes::Grouping`, and `Ransack::Nodes::Sort`. Second, the `Ransack::Visitor` class defined in [`lib/ransack/visitor.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/visitor.rb) traverses these nodes and converts them into Arel predicates through methods like `visit_Ransack_Nodes_Condition`. Finally, the ActiveRecord context in [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb) evaluates the search via the `evaluate` method, applying the Arel tree to the base relation and handling sorts at line 30 before returning a standard `ActiveRecord::Relation`.

Because the final output is an ActiveRecord relation, all standard Rails SQL inspection methods remain available.

## Inspecting SQL with ActiveRecord Methods

Once Ransack returns a relation object, you can leverage Rails native debugging tools to view the generated SQL.

### Using `to_sql` on the Result Relation

The simplest approach to debug and inspect the SQL queries generated by Ransack involves calling `to_sql` on the result relation. In [`lib/ransack/search.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/search.rb), the `result` method delegates to `@context.evaluate(self, opts)`, which returns an `ActiveRecord::Relation` compatible with standard query methods.

```ruby

# In Rails console or controller

search = Article.ransack(title_cont: 'Rails', published_eq: true)
sql = search.result.to_sql

puts sql

# => SELECT "articles".* FROM "articles" 

#    WHERE "articles"."title" ILIKE '%Rails%' AND "articles"."published" = 't'

```

### Inspecting the Search Object Tree

To examine the internal node structure before SQL generation, use the `inspect` method on the search object. This reveals the `Ransack::Nodes::Grouping` hierarchy that the visitor will traverse.

```ruby
search = Comment.ransack(body_cont: 'spam')
puts search.inspect

# => Ransack::Search<ActiveRecord::Base, base: #<Ransack::Nodes::Grouping ...>>

```

## Debugging the Arel Tree Directly

For deeper debugging, you can intercept the Arel objects before they reach ActiveRecord. The visitor pattern in [`lib/ransack/visitor.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/visitor.rb) accepts the search base and returns Arel-compatible nodes.

```ruby
search = User.ransack(name_start: 'A', age_gt: 30)

# Inspect raw Arel before it joins the relation

arel = Ransack::Visitor.new.accept(search.base)
puts arel.to_sql

# => ("users"."name" LIKE 'A%' AND "users"."age" > 30)

```

This approach is particularly useful when verifying that custom predicates in [`lib/ransack/nodes/condition.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/nodes/condition.rb) are generating valid `arel_predicate` objects.

## Enabling SQL Logging in Rails

Configure Rails to log all queries, including those generated by Ransack's context evaluation in [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb). Set the log level to debug and enable verbose query logs in your environment configuration.

```ruby

# config/environments/development.rb

Rails.application.configure do
  config.log_level = :debug
  config.active_record.verbose_query_logs = true
end

```

After configuration, executing a search will output the SQL to your logs:

```ruby
Article.ransack(title_cont: 'Rails').result.load

# Article Load (0.5ms)  SELECT "articles".* FROM "articles" 

# ↳ WHERE "articles"."title" ILIKE '%Rails%'

```

## Debugging Complex Queries and Sorts

When debugging scope-based sorting, note that Ransack treats sort strings matching defined scopes as symbols. The context applies these in the sort-handling loop beginning at line 30 of [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb).

```ruby

# Assuming Post model has a :most_recent scope

search = Post.ransack(s: 'most_recent desc')
relation = search.result

# Verify the scope application and ordering

puts relation.to_sql

```

This is critical when joins are involved, as the context also manages association handling and join building between lines 26-65 of the same file.

## Summary

- **Use `search.result.to_sql`** to view the final SQL string generated by Ransack without executing the query.
- **Inspect `Ransack::Visitor`** to examine how nodes in [`lib/ransack/nodes/condition.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/nodes/condition.rb) and related files convert to Arel predicates.
- **Enable Rails debug logging** to capture SQL output in development logs via `config.active_record.verbose_query_logs`.
- **Check [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb)** to understand how sorts, joins, and distinct options are applied to the relation.
- **Call `inspect` on the search object** to view the raw node tree before visitor processing.

## Frequently Asked Questions

### How do I see the SQL without executing the query?

Call `to_sql` on the result relation. Because `search.result` returns an `ActiveRecord::Relation` from [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb), you can invoke `search.result.to_sql` to generate the SQL string without hitting the database.

### Where does Ransack convert search parameters to SQL?

The conversion happens in two stages. First, [`lib/ransack/visitor.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/visitor.rb) transforms node objects into Arel predicates. Second, [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb) evaluates these predicates against the base relation via the `evaluate` method, producing the final SQL.

### Can I debug Ransack queries in production?

Yes, but use caution. You can temporarily enable debug logging or use `to_sql` in production consoles, but avoid verbose logging permanently due to performance overhead. For persistent debugging, use the Visitor approach to inspect Arel objects without executing queries.

### How do I inspect scope-based sorts in Ransack?

When a sort parameter matches a model scope, Ransack delegates to that scope in the sort-handling loop of [`lib/ransack/adapters/active_record/context.rb`](https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/context.rb). Verify the SQL by calling `to_sql` on the result, or check if the scope appears in the relation's order values via `search.result.order_values`.