Rails6.1になってコントローラのテンプレート指定に拡張子をつけることが推奨されなくなった
Rails 6.1以上になってCSVなどをダウンロードさせるコントローラのアクションに
def download render( csv: 'users_list', template: 'users/download.csv.ruby' ) end
のように書いているとRSpecの実行時に
DEPRECATION WARNING: Rendering actions with '.' in the name is deprecated: users/download.csv.ruby (called from download at ./app/controllers/users_controller.rb:14)
のように注意されるようになりました。これに対応するには、
def download render( csv: 'users_list', template: 'users/download' ) end
と直せばよいのですが、それだけだと今度は views/users/download.csv.ruby
が存在していてもダウンロード時に対応するフォーマットのテンプレートが存在しないというエラーになってしまいます。
なぜかというと、デフォルトではダウンロード時のリンクで
<% link_to 'ダウンロード', download_users_path %>
としたとき、ダウンロードのフォーマットはtext/htmlになっています。コントローラに拡張子を書いていたときはその拡張子に沿ってテンプレートを探してくれていましたが、コントローラから拡張子の指定をとるとデフォルトの設定が優先されます。なので、 users/download.csv.ruby
とcsvのファイルが存在していても探しにいくのはtext/html形式のファイルなので見つからない、ということになります。
text/csv 形式のファイルを探しに行ってもらうためにはダウンロードリンクを用意するときに、
<% link_to 'ダウンロード', download_users_path(format: :csv) %>
と、URLヘルパーにformat属性の指定を行えばよいです。こうすると、コントローラに拡張子を書かなくともテンプレートで用意した拡張子のファイルを探しに行ってくれるようになります。このフォーマットはconifg/routes.rbで
resources :users do get :download, on: :collection, default: { format: :csv } end
のようにconfig/routes.rbの方でも指定できます。