Heroku附加数据库生产环境Filterrific搜索功能异常排查
问题解决方案
核心问题原因
生产环境PostgreSQL严格遵循SQL规范,你代码中的关联名称大小写错误、硬编码表名/字段名大小写不匹配,导致生成的SQL语句中主表terminals未被正确加入FROM子句,触发PG::UndefinedTable错误。开发环境使用的SQLite对大小写不敏感,所以能正常运行。
具体修正步骤
- 修正关联命名格式
Rails关联必须用小写蛇形命名,你当前使用的驼峰/大写开头关联名会导致joins无法正确生成表连接:
- 把
.joins(:Manufacturers)改为.joins(:manufacturers) - 把
.joins(:TerminalType)改为.joins(:terminal_type) - 把
.joins(:FirmwarePackages)改为.joins(:firmware_packages) - 把
includes(:Notes)改为.joins(:notes)(避免includes和joins混用的歧义)
同时,references参数需要传入关联模型名(小写蛇形),而非ID字段名:
- 把
.references(:ManufacturerIds)改为.references(:manufacturers) - 把
.references(:TypeIds)改为.references(:terminal_type) - 把
.references(:TerminalIds)改为.references(:notes) - 把
.references(:TerminalFirmwarePackages)改为.references(:firmware_packages)
- 修正SQL表名与字段名
PostgreSQL默认表名/字段名为小写,硬编码大写名称会导致匹配失败,建议用Rails内置的table_name动态获取表名,避免硬编码:
- 把
Terminals.Model改为#{self.table_name}.model - 把
Manufacturers.Name改为#{Manufacturer.table_name}.name - 其他关联表字段同理,替换为小写字段名+动态表名
修正后的完整Scope代码
scope :with_search_please, ->(search_string) { return nil if search_string.blank? terms = search_string.to_s.downcase.split(/\s+/) terms = terms.map { |e| ('%' + e.gsub('*', '%') + '%').gsub(/%+/, '%') } num_or_conds = 6 self.where( terms.map { |term| "( LOWER(#{self.table_name}.model) LIKE ? OR LOWER(#{self.table_name}.termcap_model) LIKE ? OR LOWER(#{Manufacturer.table_name}.name) LIKE ? OR LOWER(#{TerminalType.table_name}.type) LIKE ? OR LOWER(#{Note.table_name}.description) LIKE ? OR LOWER(#{FirmwarePackage.table_name}.version) LIKE ? )" }.join(' AND '), *terms.map { |e| [e] * num_or_conds }.flatten ) .joins(:manufacturers).references(:manufacturers) .joins(:terminal_type).references(:terminal_type) .joins(:notes).references(:notes) .joins(:firmware_packages).references(:firmware_packages) }
补充说明
开发环境的SQLite对大小写不敏感,且对关联命名的容错性更高,所以不会暴露这类问题;而PostgreSQL严格遵循ANSI SQL规范,必须保证关联名、表名、字段名的大小写与实际数据库完全一致。
内容的提问来源于stack exchange,提问作者bbharned
相关产品推荐
相关产品推荐

