Rails中判断request.referer不存在的方法及无来源刷新报错解决
解决request.referer为空时的URI参数错误问题
这个报错的原因很直白——当你刷新页面或者直接访问该页面时,request.referer的值是nil,而URI()方法根本没法处理nil参数,直接就抛出了「bad argument (expected URI object or URI string)」错误。下面给你几个实用的修复方案,顺便修正你代码里的小问题:
方案1:先检查referer是否存在再处理
最直接的方式就是先判断request.referer有没有值,只有存在的时候才去解析URI:
class CountriesController < ApplicationController def index if request.referer.present? case URI(request.referer).path when '/artists' @countries = Country.select("countries.*, count(users.id) as artist_count") .where("users.type = 'Artist'") # 你原来的代码少了闭合引号,这里补上 .order("countries.name") .joins("left outer join users on users.country_id = countries.id") .group("countries.id, countries.name") # 可以在这里加其他来源的case分支,比如when '/fans'之类的 end else # 没有referer时的默认处理,比如返回所有国家列表,或者空统计 @countries = Country.order(:name) end end end
方案2:用Ruby安全调用避免nil报错
Ruby的&.操作符可以帮我们安全处理nil值,当request.referer为空时,URI(request.referer)&.path会直接返回nil,不会触发报错:
class CountriesController < ApplicationController def index referer_path = URI(request.referer)&.path case referer_path when '/artists' # 这里推荐用ActiveRecord的哈希条件和关联写法,更安全易读 @countries = Country.select("countries.*, count(users.id) as artist_count") .where(users: { type: 'Artist' }) .order(:name) .joins(:users) # 前提是Country模型里有has_many :users关联 .group(:id, :name) # 其他来源分支 else # 处理referer为空或者匹配不到的情况 @countries = Country.order(:name) end end end
额外注意事项
- 永远不要默认
request.referer一定存在:浏览器在很多场景下不会发送Referer头,比如直接输入URL、刷新页面、通过书签访问等,这些情况都要考虑到。 - 避免SQL注入风险:尽量用ActiveRecord的哈希条件写法(
where(users: { type: 'Artist' }))代替字符串拼接,既安全又易维护。 - 关联模型简化代码:如果你的
Country和User模型已经建立了关联(比如Country has_many :users),用joins(:users)比写原生SQL join语句更简洁可靠。
内容的提问来源于stack exchange,提问作者Papaya Labs
相关产品推荐
相关产品推荐

