Frameworks · Ruby on Rails

AI code review for Rails —
catches the mass-assignment + escape-hatch bugs.

Rails is opinionated but the opinions have escape hatches. Mass-assignment via `Model.new(params[:user])` sidesteps strong params. `.where("name = '#{name}'")` sidesteps ActiveRecord's parameterization. LGTM's Rails hints fire in the bugs + security agents whenever it sees `rails` in your Gemfile.

Auto-detected. Zero configuration.

Auto-detected when `rails` appears in your `Gemfile`. LGTM's Rails hint pack loads into the bugs + security + best-practices agents automatically.

Rails bugs that hide in plain sight

Four patterns that get past general-purpose code review because they look like idiomatic Rails. LGTM knows the shape of each.

Mass-assignment via params

`User.new(params[:user])` accepts every attribute the client sends — including `admin: true` if the model has that column. Strong params (`params.require(:user).permit(:name, :email)`) fix it, but only if every controller uses them consistently.

.where() with string interpolation

`User.where("name = '#{params[:name]}'")` is SQL injection. `.where(name: params[:name])` (hash syntax) is safe. The two forms look almost identical in code review — easy to miss the one that took a shortcut.

skip_before_action :verify_authenticity_token

Rails ships CSRF protection on by default via `protect_from_forgery`. Disabling it (usually to fix a stubborn test or make an API endpoint work) leaves the whole controller CSRF-vulnerable. Should almost always be scoped to specific actions.

N+1 queries

`@posts.each { |p| p.author.name }` triggers one query per post. `.includes(:author)` fixes it. Bullet gem catches these in dev but only for endpoints you actually hit — new code paths ship untested.

What LGTM actually catches

Three real examples — the Rails-aware bugs + security agents flag these with inline 🎯 Actionable comments and a clear "why" explanation.

criticalsql-injection
class OrdersController < ApplicationController
  def index
    name = params[:name]
    @orders = Order.where("customer_name = '#{name}'")
  end
end

What: String interpolation inside .where() clause

Why: params[:name] is attacker-controlled. Use hash form: `Order.where(customer_name: name)` — ActiveRecord parameterizes automatically. If a raw string is genuinely needed, use `.where("customer_name = ?", name)`.

highmass-assignment
class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
    @user.save
    redirect_to @user
  end
end

What: User created directly from params without strong-params filter

Why: If the User model has an `admin:boolean` column, a client can POST `user[admin]=true` and self-promote. Add a private `user_params` method with `params.require(:user).permit(:name, :email)`.

highcsrf-disabled
class ApiController < ApplicationController
  skip_before_action :verify_authenticity_token
  # every action inherits from ApiController — all CSRF-exposed.
end

What: CSRF protection disabled at the controller level

Why: Scope this to specific actions (`only: [:webhook]`) or use `protect_from_forgery with: :null_session` for genuine API endpoints. Every action that inherits from ApiController is exposed as written.

Rails starter .lgtm.yml

Skip generated schema + migrations + vendor bundles, force the rails framework slug, bump SQL / mass-assignment / CSRF to critical.

version: 1

paths:
  - pattern: "db/schema.rb"
    skip: true
  - pattern: "db/migrate/**"
    skip: true
  - pattern: "vendor/**"
    skip: true

frameworks:
  - "rails"

severity_overrides:
  sql-injection: "critical"
  mass-assignment: "critical"
  csrf-disabled: "critical"

auto_approve_docs_only: true

Commit as .lgtm.yml at your repo root, flip the Enable .lgtm.yml toggle in Repo Settings. Next PR picks it up. See all recipes →

What ships on every Rails review

Same pipeline that reviews everything else on LGTM — the Railshints just tune each agent's attention.

6 agents in parallel

Bugs, Security, Performance, Readability, Best-practices, Documentation. Each with framework-specific hints when LGTM detects your stack.

16 CI/CD detectors

LGTM Security scans your GitHub Actions, Dockerfiles, and lockfiles alongside the code review. Merge-blocking Check Run on block-level findings.

Adversarial verifier

Every finding is refuted by a skeptic LLM before it posts. Only survivors reach your PR. Kills the confident-hallucination class of false positives.

Try LGTM on your Rails repo

Free tier: 20 reviews / month, all 6 agents, all 16 security detectors. BYOK OpenAI or Anthropic. No card required.