如何解决更新后 Rails 损坏的查询 Arel::Visitors::UnsupportedVisitError而是构建一个 Arel 节点
带有 Postgresql 数据库的 Ruby on Rails 应用程序 有一个用 Arel 5.x 构造的搜索查询类:
class Sample
def url
audio_url.gsub(self.class.to_s.underscore,'user_profile_audio_sample') if audio_url
end
class << self
def search(query={},app_id='pv',page=1,per_page=20)
arel = tables.project(
profile_table[:id].as('profile_id'),audio_table[:id].as('id'),audio_table[:age].as('age'),audio_table[:audio].as('audio'),web_site_language_table[:name].as('language_name'),audio_categories_table[:name].as('category_name'),audio_categories_table[:identifier].as('category_identifier'),profile_table[:full_name].as('full_name'),profile_table[:nickname].as('nickname'),profile_table[:gender].as('gender')
).
where(profile_query).
where(genders_query(query)).
where(ages_query(query)).
where(categories_query(query)).
where(languages_query(query)).
where(website_query(app_id)).
where(audios_query).
where(audios_published).
order(profile_table[:id].desc)
sql = arel.to_sql.gsub(/SELECT/,'\\0 disTINCT ON (1)')
paginate_by_sql(sql,page: page,per_page: per_page)
end
protected
def profile_query
profile_table[:nickname].not_eq(nil)
end
def audios_query
audio_table[:id].not_eq(nil)
end
def audios_published
audio_table[:published].eq(true)
end
Def Languages_query(query={})
if valid_query_param? query[:languages]
audio_web_site_language_table[:web_site_language_id].in(query[:languages].select &:present?)
else
true
end
end
def website_query(app_id)
web_sites_table[:app_id].eq(app_id)
end
def categories_query(query)
if valid_query_param? query[:categories]
audio_table[:audio_category_id].in(query[:categories].select &:present?)
else
true
end
end
def ages_query(query)
if valid_query_param? query[:ages]
audio_table[:age].in(query[:ages].select &:present?)
else
true
end
end
def genders_query(query)
if valid_query_param? query[:genders]
profile_table[:gender].in(query[:genders].select &:present?)
else
true
end
end
def valid_query_param?(name)
name.present? && !name.select(&:present?).empty?
end
def tables
profile_table \
.join(audio_table,Arel::Nodes::OuterJoin) \
.on(profile_table[:id].eq(audio_table[:user_profile_id])) \
.join(audio_categories_table,Arel::Nodes::OuterJoin) \
.on(audio_table[:audio_category_id].eq(audio_categories_table[:id])) \
.join(audio_web_site_table,Arel::Nodes::OuterJoin) \
.on(audio_table[:id].eq(audio_web_site_table[:audio_id])) \
.join(audio_web_site_language_table,Arel::Nodes::OuterJoin) \
.on(audio_web_site_table[:id].eq(audio_web_site_language_table[:audio_web_site_id])) \
.join(web_site_language_table,Arel::Nodes::OuterJoin) \
.on(audio_web_site_language_table[:web_site_language_id].eq(web_site_language_table[:id])) \
.join(web_sites_table,Arel::Nodes::OuterJoin) \
.on(web_site_language_table[:web_site_id].eq(web_sites_table[:id]))
end
def profile_table
Arel::Table.new(:user_profiles)
end
def audio_table
Arel::Table.new(:user_profile_audio_samples)
end
def audio_web_site_table
Arel::Table.new(:user_profile_audio_sample_web_sites)
end
def audio_web_site_language_table
Arel::Table.new(:user_profile_audio_sample_web_site_languages)
end
def web_site_language_table
Arel::Table.new(:web_site_languages)
end
def audio_categories_table
Arel::Table.new(:audio_categories)
end
def web_sites_table
Arel::Table.new(:web_sites)
end
end
end
SELECT disTINCT ON (1)
"user_profiles"."id" AS profile_id,"user_profile_audio_samples"."id" AS id,"user_profile_audio_samples"."age" AS age,"user_profile_audio_samples"."audio" AS audio,"web_site_languages"."name" AS language_name,"audio_categories"."name" AS category_name,"audio_categories"."identifier" AS category_identifier,"user_profiles"."full_name" AS full_name,"user_profiles"."nickname" AS nickname,"user_profiles"."gender" AS gender
FROM "user_profiles"
LEFT OUTER JOIN "user_profile_audio_samples" ON "user_profiles"."id" = "user_profile_audio_samples"."user_profile_id"
LEFT OUTER JOIN "audio_categories" ON "user_profile_audio_samples"."audio_category_id" = "audio_categories"."id"
LEFT OUTER JOIN "user_profile_audio_sample_web_sites" ON "user_profile_audio_samples"."id" = "user_profile_audio_sample_web_sites"."audio_id"
LEFT OUTER JOIN "user_profile_audio_sample_web_site_languages" ON "user_profile_audio_sample_web_sites"."id" = "user_profile_audio_sample_web_site_languages"."audio_web_site_id"
LEFT OUTER JOIN "web_site_languages" ON "user_profile_audio_sample_web_site_languages"."web_site_language_id" = "web_site_languages"."id"
LEFT OUTER JOIN "web_sites" ON "web_site_languages"."web_site_id" = "web_sites"."id"
WHERE "user_profiles"."nickname" IS NOT NULL AND 't' AND 't' AND 't' AND 't' AND "web_sites"."app_id" = 'pv' AND "user_profile_audio_samples"."id" IS NOT NULL AND "user_profile_audio_samples"."published" = 't'
ORDER BY "user_profiles"."id" DESC
LIMIT 20 OFFSET 0
升级到 Rails 6.1 后,我开始收到错误消息: Arel::Visitors::UnsupportedVisitError:不支持的参数类型:TrueClass。而是构建一个 Arel 节点。 我相信它与 audios_published 方法有关。我尝试使用 Arel::Node::Binary 和 Arel::Node::Quoted 但我没有足够的了解我需要使用哪些 Arel 类。另外我认为其他方法需要类似的更改,而不仅仅是audios_published。 将查询返回到与升级前相同的状态的模式是什么?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。