Document Solid Queue batch jobs in the Active Job guide [ci-skip] - #1
Open
jpcamara wants to merge 30 commits into
Open
Document Solid Queue batch jobs in the Active Job guide [ci-skip]#1jpcamara wants to merge 30 commits into
jpcamara wants to merge 30 commits into
Conversation
`average` casts the result to `BigDecimal` for integer and decimal columns, not to `Float`. Float is only returned for float columns, which the "given column's type" case already covers.
…skip] The dirty tracking values in the example are those of a persisted record, but `u` is built with `User.new` and never saved, so `color_was` is `nil` and `color_change` is `[nil, 'green']`. Create the record so that the documented values hold.
Further improve Reflextion#extensions
`content.rb` and `markdown_conversion.rb` declare `# :markup: markdown`, but their doc comments used RDoc's `+text+` and `<tt>` markup, which renders literally under that directive. Use backticks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013fCL4kH4H9z8CiKWtPVke4
`Content#to_markdown` built the `<action-text-markdown>` wrapper inline, so the tag name lived in `Content` while `MarkdownConversion` matched the same literal in two private constants. Extract the wrapper into `MarkdownConversion.render_attachment`, next to a shared `RAW_MARKDOWN_TAG_NAME` the constants now use. No behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013fCL4kH4H9z8CiKWtPVke4
`Content#to_markdown` wraps attachment Markdown in `<action-text-markdown>` so the converter emits it without escaping, but the converter could not tell that element from one a user typed into a rich text body. A body holding a literal `<action-text-markdown>` therefore had its text emitted verbatim, bypassing the URI scheme check in `MarkdownConversion#markdown_link`. Unwrap the element in `Content.fragment_by_canonicalizing_content`, which runs for every `Content` built from outside the framework, including bodies loaded from the database. Attachment markup is added afterwards on a `canonicalize: false` `Content`, so it still passes through. `fragment_by_unwrapping_raw_markdown_tags` sits next to `render_attachment` and the tag name they share, so both sides of that boundary are in one file. The order they run in is what makes the fix work, so a test asserts it by name rather than leaving it to the attachment tests that would incidentally fail. `Fragment#to_markdown` and `MarkdownConversion.node_to_markdown` neither canonicalize nor render attachments, and are documented as unsafe for untrusted content. ref: https://hackerone.com/reports/3727743 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LPp9kjB67z8k27f9uv4dq7
…turn-type Fix the documented return type of AVG calculations
…c-example Fix the Active Record Store dirty tracking documentation example
`fetch_indexes` builds `optional_columns` before it looks at `tables`, and `supports_expression_index?` asks for `database_version`, so `indexes([])` opens the connection just to read nothing. Return early like the SQLite reader already does. This fails `SchemaStatementsTest#test_an_empty_list_reads_nothing` whenever it runs right after a test that re-establishes the connection, which CI hits often: https://buildkite.com/rails/rails/builds/132802/canvas?sid=01a0320e-c18f-4c26-b4d3-84069b6971fb&tab=output#01a0320e-c1f8-4cab-b837-86aa84688c4b/L11493
…th-an-empty-list Don't touch the connection in MySQL's `fetch_indexes` for an empty list
`@extension` (singular) is undefined, and `nil.frozen?` is always true, causing unnecessary `dup` calls.
…-typo Fix typo in Reflection initializer
The pattern of duping a Hash to later append a key to it
isn't ideal because if the original Hash was full, its
copy will be too and it will need to be reallocated on insertion.
By using the `{ **base, new_key: 1 }` pattern, we allow Ruby to
directly allocate a hash of the right size, at least on Ruby 4.1.
Ref: ruby/ruby#18344
This callsite has been identified as a common source of such
reallocations in the ruby-bench suite (lobsters and shipit).
url_for: use Hash splat to append keys
…pe-issue Allow `translate`'s `scope:` argument to resolve relative i18n keys with leading period
Strip user-supplied `<action-text-markdown>` while canonicalizing
The block form only works for blocking query execution, and we want QueryIntent to be more flexible. This also makes for a cleaner break: the current version had already deprecated the historical log(sql, ..) form; now the method is deprecated wholesale without needing to check any parameter types.
We've previously relied on the caller 1) being inside a rescue, and 2) immediately raising the return value, to set the cause. In anticipation of callers prefering to retain the translated exception for later use, let's instead make sure we return a fully-populated exception object, setting the cause at the same time we set the backtrace.
Instead of directly setting the raw_result on the intent, and immediately raising on error, we now involve the intent in both. Where a result is available, the intent is given a chance to act on that information (updating related internal state, owning the log-finish). In the case of an error, that is also delivered to the intent, where it will be stored, and only raised when a caller asks for the result. (All existing callers ask immediately after executing the intent, so this doesn't practically defer any exceptions right now -- no change in existing behaviour.)
For safety, ensure that all intents that have started do get finished, even if the caller somehow forgets about them.
Warnings are part of a query's delivered outcome: store warnings on the intent, and run the configured warning action when the caller observes that outcome, so async execution doesn't raise on the worker's behalf or mask the query error.
This reverts commit f72c932.
Some storage representations compare through database expressions that do not belong in Ruby casting or serialization. Allow Active Record types to define a symmetric comparison expression for hash predicates while retaining ordinary bind serialization.
A join compares stored values, so each side needs its own type's expression.
Query predicate expressions for Active Record types, take 2
Drive result delivery through QueryIntent
jpcamara
force-pushed
the
solid-queue-batch-jobs-guide
branch
from
August 24, 2026 21:22
7f17624 to
da1c4de
Compare
Solid Queue 1.7 added batches, but the Active Job Basics guide did not cover them. Add a Batch Jobs section under Default Backend: Solid Queue, following the shape of the neighboring sections: motivate the feature with a row-by-row import, list the three callbacks and when each runs, walk through the example the way the concurrency section walks through its options, and close with a NOTE on the migration applications that installed Solid Queue before 1.7 need, plus a link to the Solid Queue documentation for the deeper details. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jpcamara
force-pushed
the
solid-queue-batch-jobs-guide
branch
from
August 24, 2026 21:25
da1c4de to
657c23a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation / Background
Solid Queue 1.7 added support for grouping jobs into batches (rails/solid_queue#142), but the Active Job Basics guide doesn't mention them. Since the guide has a substantial "Default Backend: Solid Queue" section covering the backend's other features (concurrency controls, recurring tasks, transactional integrity), batches belong alongside them.
Detail
Adds a
### Batch Jobssubsection after Recurring Tasks, following the structure of the neighboring sections: a motivating use case (importing a file row by row, then notifying), the three callbacks and when each fires, a worked example with an "In the above example" walkthrough mirroring the Concurrency Controls section, a NOTE on the migration applications that installed Solid Queue before 1.7 need, and a closing link to the Solid Queue documentation for deeper details.Every claim was verified against the released solid_queue 1.7.0 gem. Documentation only, no behavior change.
mdlpasses with the repository's style configuration.Checklist
Before submitting the PR make sure the following are checked: