タイミングの問題があると思います。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
で十分でしょう。