Agents on Rails, query method and more Rails 8.1 introduces Agents on Rails, a new AI integration framework, alongside support for the HTTP QUERY method and several Active Storage and schema reader improvements. The Rails team announced Agents on Rails on August 12, 2026, with the first benchmark report released the next day, aiming to simplify building AI-powered Rails applications. Other changes include configurable ffmpeg/ffprobe arguments, a class-based variant processor, and a fix for LengthValidator crashes with proc minimums. Hi, Wojtek https://x.com/morgoth85 here. Let’s explore this week’s news in the Rails. Agents on Rails https://rubyonrails.org/ai Read the announcement https://rubyonrails.org/2026/8/12/llm-benchmarking-project and the first benchmark report https://rubyonrails.org/2026/8/13/agents-on-rails-the-first-benchmark-report . Add support for the HTTP QUERY method https://github.com/rails/rails/pull/57973 QUERY is a safe and idempotent HTTP method that conveys the query in the request content, making it suitable for queries too large or structured for a URL query string: config/routes.rb query "search", to: "search index" match "filter", to: "search filter", via: :query request handling request.query? = true request.request method symbol = :query integration tests query "/search", params: { filters: { status: "active" } }, as: :json Show bin/console startup banner based on IRB https://github.com/rails/rails/pull/58455 Show a Rails-flavored startup banner a small logo, Rails/Ruby version, a rotating tip about console helpers like reload , and Rails.root when starting bin/rails console . Set RAILS TIPS=false to hide the rotating tip. Allow ffmpeg and ffprobe input arguments to be configured https://github.com/rails/rails/pull/58461 Two new configuration parameters are introduced. config.active storage.video preview input arguments is passed to ffmpeg before -i , and config.active storage.ffprobe arguments is passed to ffprobe before the file path. Both default to empty string. ffmpeg ’s flags are position dependent, and these parameters carry the ones that apply to the input, such as -codec whitelist, -f, and -protocol whitelist. For example, an application that accepts only H.264 video with AAC audio: config.active storage.video preview input arguments = "-codec whitelist h264,aac" config.active storage.ffprobe arguments = "-codec whitelist h264,aac" Allow config.active storage.variant processor to be set to a class https://github.com/rails/rails/pull/58384 The class must implement the interface defined by ActiveStorage::Transformers::Transformer . Active Storage then uses it for variant processing: config.active storage.variant processor = CustomTransformer The schema readers answer for many tables at once https://github.com/rails/rails/pull/58421 indexes / primary keys / foreign keys / check constraints / exclusion constraints / unique constraints now accept a list of tables and answer for all of them at once: js connection.indexes :users = IndexDefinition, ... connection.indexes :users, :posts = { "users" = ... , "posts" = ... } Fix LengthValidator crash with proc minimum and nil value https://github.com/rails/rails/pull/58428 The proc was resolved only when the value was present, so for a nil value it leaked unresolved into the error message and was invoked with the message options hash instead of the record. It is now resolved before the error is built, producing the expected “is too short” message. php validates length of :title, minimum: - record { record.min length } title = nil now yields "is too short minimum is N characters " instead of raising NoMethodError Use bind parameters for array-form arguments in find by sql / count by sql https://github.com/rails/rails/pull/58427 The API doc claims parity with where , but array-form values were eagerly interpolated via sanitize sql . Deprecate create alias of insert in connection adapters https://github.com/rails/rails/pull/58426 insert / update / delete correspond to their SQL DML verbs, but create reads like DDL create table / create database rather than the INSERT it actually performs. Split keyword arguments off args on Rails.application.middleware entries https://github.com/rails/rails/pull/58420 Middleware entries now expose keyword arguments through a new kwargs accessor. args previously bundled kwargs as a trailing hash inside the positional array via Hash.ruby2 keywords hash . It now returns positional arguments only. Allow to configure ERB options through ActionView::Base https://github.com/rails/rails/pull/58359 The ActionView::Template::Handlers::ERB class is now private API. Applications that used to configure ERB options such as escape ignore list now need to do this on the ActionView::Base class or on the railtie config.action view configuration. Append TRADITIONAL instead of STRICT ALL TABLES to MySQL’s sql mode by default https://github.com/rails/rails/pull/58350 On environments whose global sql mode is empty — most notably Amazon RDS and Aurora MySQL default parameter groups — appending only STRICT ALL TABLES leaves out NO ZERO IN DATE , NO ZERO DATE , and ERROR FOR DIVISION BY ZERO , which MySQL 5.7+ has otherwise made part of its own default. Appending TRADITIONAL closes the gap. Allow ActiveSupport::ProxyLogger to ignore messages by pattern https://github.com/rails/rails/pull/58328 Useful to silence noisy logs from gems that your application may not care about, without needing to change the log level and losing other useful logs. Add Pacific Time Canada and Alberta Time zone mappings https://github.com/rails/rails/pull/58321 Adds two friendly zone mappings: Change the shape of ActiveRecord::Migration::CommandRecorder commands https://github.com/rails/rails/pull/58239 Each recorded migration command is now stored as cmd, args, kwargs, block 4-element instead of cmd, args, block 3-element with kwargs bundled into a trailing hash inside args . Code that inspects recorder.commands directly needs to adapt to the new tuple shape. Fix normalizes to run before the underlying type validates an assigned value https://github.com/rails/rails/pull/57846 When normalizes was combined with another type that rejects invalid input such as an Active Record enum , the underlying type’s assert valid value ran against the raw, un-normalized value and raised before normalization had a chance to run. The normalization is now applied first, so a value like “ Pending “ is normalized to “pending” and accepted by the enum. You can view the whole list of changes here. Until next time Subscribe https://world.hey.com/this.week.in.rails to get these updates mailed to you.