如何阻止Ransack/ActiveAdmin为关联模型作用域过滤器追加_contains
解决ActiveAdmin关联模型过滤器自动追加
_contains后缀的问题 问题原因
你在关联User的模型页面使用filter :user_matches_name, as: :string时,ActiveAdmin默认会把这个过滤器识别为字段查询,自动给作用域名称追加_contains谓词,但你的user_matches_name是自定义作用域而非字段,因此出现方法不存在的报错。而在User自己的页面中,Ransack能正确识别这是自定义作用域,所以不会追加后缀。
解决步骤
1. 在关联模型中定义转发作用域
首先在你的主模型(比如MyModel)中,创建一个关联User的作用域,将查询转发到User的matches_name作用域:
# app/models/my_model.rb class MyModel < ApplicationRecord belongs_to :user # 定义关联作用域,调用User的matches_name逻辑 scope :user_matches_name, ->(query) { joins(:user).merge(User.matches_name(query)) } # 允许Ransack调用这个自定义作用域 def self.ransackable_scopes(_auth_object = nil) [:user_matches_name] end end
2. 自定义过滤器的处理逻辑
在ActiveAdmin的主模型页面配置中,使用lambda手动控制过滤器的查询逻辑,避免自动追加后缀:
# app/admin/my_model.rb ActiveAdmin.register MyModel do filter :user_matches_name, as: :string, label: "User" do |search, _predicate, value| # 仅当输入值存在时,调用自定义作用域 search.user_matches_name(value) if value.present? end end
这样配置后,输入框的内容会直接传入user_matches_name作用域,Ransack不会再自动生成_contains相关的方法,报错问题即可解决。
内容的提问来源于stack exchange,提问作者Dan Monego
相关产品推荐
相关产品推荐

