activerecord-hackery/ransack · error · ArgumentError
A context is required to translate attributes
Error message
A context is required to translate attributes
What it means
Ransack::Translate.attribute resolves human-readable names for an attribute (or attribute+predicate) key via I18n, using the search context's model class and its ancestors to build translation lookup keys ('ransack.attributes.<model>.<key>', activerecord.attributes..., etc.). It requires the calling search's context to be passed in options[:context]; without it there is no model to translate against and this ArgumentError is raised.
Source
Thrown at lib/ransack/translate.rb:20
I18n.load_path += Dir[
File.join(File.dirname(__FILE__), 'locale'.freeze, '*.yml'.freeze)
]
module Ransack
module Translate
class << self
def word(key, options = {})
I18n.translate(:"ransack.#{key}", default: key.to_s)
end
def predicate(key, options = {})
I18n.translate(:"ransack.predicates.#{key}", default: key.to_s)
end
def attribute(key, options = {})
unless context = options.delete(:context)
raise ArgumentError, "A context is required to translate attributes"
end
original_name = key.to_s
base_class = context.klass
base_ancestors = base_class.ancestors.select {
|x| x.respond_to?(:model_name)
}
attributes_str = original_name.dup # will be modified by ⬇
predicate = Predicate.detect_and_strip_from_string!(attributes_str)
attribute_names = attributes_str.split(/_and_|_or_/)
combinator = attributes_str =~ /_and_/ ? :and : :or
defaults = base_ancestors.map do |klass|
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
end
defaults << options.delete(:default) if options[:default]
translated_names = attribute_names.map do |name|
attribute_name(context, name, options[:include_associations])View on GitHub (pinned to e82f6bab39)
Solutions
- Pass the search context: Ransack::Translate.attribute('name_cont', context: @q.context)
- Prefer the higher-level API: @q.translate('name_cont') or the form builder's label, which forward the context automatically
- In specs, build a real search first: search = Person.ransack(name_cont: 'x'); use search.context
Example fix
# before
Ransack::Translate.attribute('name_cont')
# => ArgumentError: A context is required to translate attributes
# after
search = Person.ransack(name_cont: 'x')
Ransack::Translate.attribute('name_cont', context: search.context) Defensive patterns
Strategy: validation
Validate before calling
search = Person.ransack(name_cont: 'x')
opts = { context: search.context }.merge(user_opts)
Ransack::Translate.attribute('name_cont', opts) Type guard
def translatable_attribute_call?(key, options) options.key?(:context) && options[:context].respond_to?(:klass) end
Prevention
- Always pass context: search.context when calling Translate.attribute directly
- Prefer @q.translate / form-builder labels, which wire the context for you
- In extracted helpers, thread the original options hash through unmodified so :context survives
When it happens
Trigger: Calling Ransack::Translate.attribute('name_cont') directly with no options; calling search.base.conditions.first.attributes.first.translate(key, options) with options that omit :context (the Grouping#translate path merges context: context, but a custom call may not); helper code that copies the translate API without forwarding the context.
Common situations: Writing custom label helpers or decorators that use Translate.attribute for consistent I18n; refactoring view code and losing the context: keyword; testing translation logic in isolation without constructing a search first.
Related errors
- A context is required to translate associations
- #{type} cannot be converted to an ARel join type
- #{value} cannot be converted to a Class
- Don't know what context to use for #{object}
- No Ransack::Search object was provided to #{method_name}!
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/e3cba1b38b48c0d2.
Report an issue: GitHub.