コントローラのアクションをajaxにだけ許可したい場合、アクション自身にこう書くこともできます。
def sugoi_action
raise AbstractController::ActionNotFound unless request.xhr?
# 何かすごい処理
end
でもせっかくroutesがあるのに、アクションでそれぞれ制御するのはできれば避けたいです。こういう情報はひとまとまりで扱いたいです。
constraintsでajaxだけを許可する
railsのルーティングでは、constraintsというハッシュでそのアクションを許可する条件を指定できます。
例えばこんな風に。
config/routes.rb
match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }
constraintsは標準ではajaxリクエストを判定するオプションは用意されていません。
でもご安心を。constraintsは独自に作ることもできるのです。
今回はこんな感じでajaxだけを許可するconstraintsを作ってみました。
lib/constraints/only_ajax_constraints.rb
class OnlyAjaxRequest
def self.matches?(request)
request.xhr?
end
end
config/routes.rb
get 'hogehoge' => :hogehoge, :constraints => OnlyAjaxRequest
lib/constraints
へのパスを通します。
config/application.rb
config.autoload_paths += %W(#{config.root}/lib/constraints)
これで、直接アクセスしようとした時に404が帰ってくるようになりました!