kikeda1104's blog

備忘録・技術に関することを書いています。(webエンジニア)

constraintsの利用について

後輩にvimの折り畳み開閉のショートカットキーを聞かれてて、忘れてたのに落ち込んだり、

参加したセミナーでテストコードに関する有益な話を聞けてほっこりしてます。

コミュ力って重要。

Railsのroutes.rbで、ルーティングを無条件で利用すると、public下の置いているファイルとルーティングが当たってしまうので、

これを回避するためにURIを変えるか。制限を入れるかを考えていて、制限を入れることにしました。

constraintsを使って定義する。

環境

constraints

定義したルーティングに制限を追加することできます。

# config/routes.rb
Rails.application.routes.draw do
   get 'users/:user_id' => 'users#show', constraints: /\d+/
end

これは、ブロックも利用できて、複数のルーティングに制限を加える際に利用できる。

Rails.application.routes.draw do
   constraints /\d+/ do
     get 'welcome/:id' => 'welcome#show'
     ...
   end
end

今回は、DBの値を利用した制限を追加する形で実装を進めていてconstraintsのファイル保存場所について

appを検討したが、ひとまずlibに保存しています。

まず、lib/autoloadを起動時に自動で読み込むようにします。

# config/application.rb
...
config.autoload_paths += %W(#{Rals.root}/lib)
...
# lib/autoload/constraints/zone_constraint.rb
class ZoneConstraint
  def matches?(request)
    paths = request.path_info&.split('/')&.reject(&:blank?)
    paths.size.times do |i|
      case i
      when 0
        fail if ExampleA.find_by(key: areas[i]).blank?
      when 1
        fail if ExampleB.find_by(key: areas[i]).blank?
      when 2
        fail if ExampleC.find_by(key: areas[i]).blank?
      else
        fail
      end
    end
    true
  rescue
    false
  end
end

最後にroutes.rbに制限を加えます。

# config/routes.rb

constaints ZoneConstraint do
  get ':example_a/:example_b/:example_c' => 'example#index
  ...
end

データベースに保存されていない場合、ルーティングを参照しないようにします。

参考

Rails3 事始め: [Rails3] 現在のURLを取得(request オブジェクト)

rails routing constraintsについて | 日々雑記

constraintsの意味 - 英和辞典 Weblio辞書

Rails のルーティング | Rails ガイド

Railsアプリのモジュールはどこに置くべきか問題 (公開版)