{"record":{"id":"7881c29851d7e968","repo":"activerecord-hackery/ransack","slug":"don-t-know-how-to-klassify-obj","errorCode":null,"errorMessage":"Don't know how to klassify #{obj}","messagePattern":"Don't know how to klassify #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/ransack/adapters/active_record/context.rb","lineNumber":101,"sourceCode":"              end\n            end\n          end\n          exists\n        end\n\n        def table_for(parent)\n          parent.table\n        end\n\n        def klassify(obj)\n          if Class === obj && ::ActiveRecord::Base > obj\n            obj\n          elsif obj.respond_to? :klass\n            obj.klass\n          elsif obj.respond_to? :base_klass\n            obj.base_klass\n          else\n            raise ArgumentError, \"Don't know how to klassify #{obj}\"\n          end\n        end\n\n        # All dependent Arel::Join nodes used in the search query.\n        #\n        # This could otherwise be done as `@object.arel.join_sources`, except\n        # that ActiveRecord's build_joins sets up its own JoinDependency.\n        # This extracts what we need to access the joins using our existing\n        # JoinDependency to track table aliases.\n        #\n        def join_sources\n          base, joins = begin\n            alias_tracker = @object.alias_tracker\n            constraints   = @join_dependency.join_constraints(@object.joins_values, alias_tracker, @object.references_values)\n\n            [\n              Arel::SelectManager.new(@object.table),\n              constraints","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/activerecord-hackery/ransack/blob/e82f6bab3956c5597e7debbefa218d9e94e58ceb/lib/ransack/adapters/active_record/context.rb#L83-L119","documentation":"Ransack's ActiveRecord adapter raises this ArgumentError from Context#klassify when it is handed an object it cannot reduce to an ActiveRecord model class: it accepts an AR::Base subclass directly, anything responding to #klass (associations, relations), or anything responding to #base_klass (join dependency parts). This method sits on the traverse path, so it fires while Ransack resolves an association chain to a concrete class.","triggerScenarios":"Searching a polymorphic association with a '_of_Model_type' suffix where Model is not an ActiveRecord::Base subclass (e.g. notable_of_NotAModel_type, or a class name that resolves to a PORO/mongo object); traversing an association whose reflection target does not expose klass/base_klass (non-AR association types, some composite-key gems).","commonSituations":"Trying to search polymorphic belongs_to associations directly, which Ransack does not support without the explicit _of_Class_type disambiguation; a typo'd class name in the _of_ suffix (Kernel.const_get resolves it to something unexpected); associations defined by gems that break the reflection contract after a Rails upgrade.","solutions":["Verify the association chain you are searching targets a real ActiveRecord model (check MyClass < ActiveRecord::Base)","For polymorphic associations, use the '_of_Model_type' form with a valid AR model name, e.g. q[notable_of_Article_type_name_cont]","If the class name in the suffix is misspelled, fix it — unpolymorphize_association resolves it via Kernel.const_get before klassify sees it","Search a concrete association instead of the polymorphic one (e.g. go through a has_many through)"],"exampleFix":"# before (params)\nq = { 'notable_name_cont' => 'foo' }  # polymorphic, no concrete class\nPerson.ransack!(q)\n\n# after\nq = { 'notable_of_Article_type_title_cont' => 'foo' }\nPerson.ransack!(q)","handlingStrategy":"validation","validationCode":"# before searching a polymorphic chain, verify the target resolves to an AR model\nassoc_klass = Person.reflect_on_association(:notable)&.klass\npolymorphic = Person.reflect_on_association(:notable)&.polymorphic?\nraise ArgumentError, 'cannot search polymorphic notable directly' if polymorphic\n\n# for _of_X_type params, validate X is one of your AR models:\nallowed = %w[Article Comment].freeze\nparam_class = params[:q].to_s[/notable_of_(\\w+)_type/, 1]\nreturn if param_class && !allowed.include?(param_class)","typeGuard":"def ar_model?(obj)\n  obj.is_a?(Class) && obj < ActiveRecord::Base\nend\n\ndef klassifiable?(obj)\n  ar_model?(obj) || obj.respond_to?(:klass) || obj.respond_to?(:base_klass)\nend","tryCatchPattern":"begin\n  Person.ransack!(params[:q]).result\nrescue ArgumentError, Ransack::InvalidSearchError => e\n  Rails.logger.info(\"Unsearchable association chain: #{e.message}\")\n  Person.all # degrade gracefully\nend","preventionTips":["Never expose raw polymorphic association names in search forms — use the _of_Model_type form with a fixed model dropdown","Validate every '_of_X_type' class suffix against an explicit model allowlist in the controller","Add reflection specs asserting searched associations point at AR models (reflect_on_association(:x).klass < ActiveRecord::Base)"],"tags":["ruby","rails","ransack","activerecord","polymorphic","associations"],"backgroundTag":"unresolvable-model-class","analyzedSha":"e82f6bab3956c5597e7debbefa218d9e94e58ceb","analyzedAt":"2026-08-21T19:30:23.639Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}