我猜你有时间问题。当您的模型在生产模式下加载时,您的路由表Rails.application.routes
可能尚未构建;但是,在开发模式下,您的模型可能会在每次请求时重新加载,因此Rails.application.routes
将在您的模型加载和validates
调用时填充:
validates :alias, :exclusion => { :in => Rails.application.routes.routes.map { ... } }
被执行。
一个简单的解决方案是切换到验证方法:
class Model < ActiveRecord::Base
validate :alias_isnt_a_route, :if => :alias_changed?
private
def alias_isnt_a_route
routes = Rails.application.routes.routes.map { ... }
if(routes.include?(alias))
errors.add(:alias, "Alias #{alias} is already used for a route")
end
end
这样,您在Rails.application.routes
需要检查别名之前不会查看,到那时,路线将已加载。当然,如果您愿意,您可以缓存路由前缀列表。
您还需要在应用程序的初始化阶段添加一些完整性检查。您的生产环境中的某个人可能会在您在开发'pancakes'
时添加路线时添加,例如,作为他们的别名/pancakes
:您的验证将错过这个新的冲突。像这样简单的东西:
config.after_initialize do
Rails.application.reload_routes! # Make sure the routes have been loaded.
# Compare all the existing aliases against the route prefixes and raise an
# exception if there is a conflict.
end
在你的config/application.rb
就足够了。