質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

VirtualBox

VirtualBoxは、現在米オラクル社が開発している、 x86仮想化ソフトウェア・パッケージの一つです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

3回答

1996閲覧

【助けて下さい】 なぜか初回アクセス時のみ params([:controller])がnilになってしまいます。

DelphiumG

総合スコア3

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

VirtualBox

VirtualBoxは、現在米オラクル社が開発している、 x86仮想化ソフトウェア・パッケージの一つです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2020/07/24 13:45

編集2020/07/26 03:58

前提・実現したいこと

Rails スタッフ画面、管理者画面、顧客画面を作成し、それぞれ異なるテンプレート(レイアウト)を
当てはめたいと考えております。

そこで、

application_controller.rb
にて
コントローラー名params([:controller])に応じて
layoutメソッドに ことなるテンプレート名をあてはめようと下記のように

params([:controller]).match(%r{\A(staff|admin|customer)/})

paramsとmatchを使ってコントローラー名(staff or admin or customer)を取得し

layout メソッドにテンプレート名としてセットするようにいたしました。

発生している問題・エラーメッセージ

bin/rails s -b 0.0.0.0

してhttp://localhost:3000/staff にアクセスすると(customer,adminでも同様です)
下記のエラーメッセージが表示されますが、

一度ブラウザをリロードすると
エラーが解消され、意図したレイアウトの画面が表示されます。

 なぜ、最初だけエラーが表示されて、画面を更新するとエラーが解消するのかが
わかりません。

 かれこれ まる2日間、悩んでいます・・・。
なにか、解決の手がかりをご教授いただけましたら幸いです。

terminal

1Started GET "/staff" for 172.18.0.1 at 2020-07-24 11:22:05 +0000 2 3NoMethodError (Could not render layout: undefined method `match' for nil:NilClass): 4 5app/controllers/staff/top_controller.rb:2:in `<class:TopController>' 6app/controllers/staff/top_controller.rb:1:in `<main>'

ブラウザのエラー画面

該当のソースコード

applicationcontroller

1app/controllers/application_controller.rb 2class ApplicationController < ActionController::Base 3 4 layout :set_layout 5 6 private 7 def set_layout 8 if params[:controller].match(%r{\A(staff|admin|customer)/}) 9 Regexp.last_match[1] 10 else 11 "customer" 12 end 13 end 14end

topcontroller

1app/controllers/staff/top_controller.rb 2 3class Staff::TopController < ApplicationController 4 render action: "index" 5end

routes

1config/routes.rb 2 3Rails.application.routes.draw do 4 namespace :staff do 5 root "top#index" 6 end 7 8 namespace :admin do 9 root "top#index" 10 end 11 12 namespace :customer do 13 root "top#index" 14 end 15end

viewslayoutsstaff

1app/views/layouts/staff.html.slim 2 3doctype html 4html 5 head 6 title= document_title 7 = csrf_meta_tags 8 = csp_meta_tag 9 = stylesheet_link_tag "staff", media: "all", "data-turbolinks-track": "reload" 10 = javascript_pack_tag "application", "data-turbolinks-track": "reload" 11 body 12 #wrapper 13 = render "shared/header" 14 #container 15 = yield 16 = render "shared/footer"

viewstafftopindex

1app/views/staff/top/index.html.slim 2 3- @title = "職員トップページ" 4h1 = @title

Gemfile

1source 'https://rubygems.org' 2git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 4ruby '2.6.4' 5 6gem "rails", "~> 6.0.0" 7gem "pg", ">= 0.18", "< 2.0" 8gem "puma", "~> 3.11" 9gem "sass-rails", "~> 5" 10gem "webpacker", "~> 4.0" 11gem "turbolinks", "~> 5" 12gem "jbuilder", "~> 2.7" 13gem 'slim-rails' 14gem 'html2slim' 15 16gem "bootsnap", ">= 1.4.2", require: false 17 18gem "bcrypt" 19gem "rails-i18n" 20gem "kaminari" 21gem "date_validator" 22gem "valid_email2" 23gem "nokogiri" 24 25group :development, :test do 26 gem "byebug", platforms: [:mri, :mingw, :x64_mingw] 27end 28 29group :development do 30 gem "web-console", ">= 3.3.0" 31 gem "listen", ">= 3.0.5", "< 3.2" 32 gem "spring" 33 gem "spring-watcher-listen", "~> 2.0.0" 34end 35 36group :test do 37 gem "capybara", ">= 2.15" 38 gem "selenium-webdriver" 39 gem "webdrivers" 40 gem "rspec-rails" 41 gem "factory_bot_rails" 42end

試したこと1

#####byebugを使ってparams[:controller]を調べた
byebugを使って、application_controller.rb で
params[:controller]を調べましたら、
サーバー起動後の最初のget リクエスト時は
params[:controller]はnilになっていました。

下記はターミナル画面

terminal

1Started GET "/staff" for 172.18.0.1 at 2020-07-24 12:32:38 +0000 2 3[3, 12] in /apps/baukis2/app/controllers/application_controller.rb 4 3: layout :set_layout 5 4: private 6 5: def set_layout 7 6: 8 7: byebug 9=> 8: if params[:controller].match(%r{\A(staff|admin|customer)/}) 10 9: Regexp.last_match[1] 11 10: else 12 11: "customer" 13 12: end 14(byebug) params[:controller] 15nil 16

byebugを抜けてから、サーバーを再起動し、
その後、byebugの場所を変えて
http://localhost:3000/staff にアクセスし、同じエラーが出ますので、
エラー発生後にブラウザを更新するとbyebugが作動しました。

params[:controller]を確認すると"staff/top"がセットされていました。

terminal

1Started GET "/staff" for 172.18.0.1 at 2020-07-24 12:24:03 +0000 2Processing by Staff::TopController#index as HTML 3 4[3, 12] in /apps/baukis2/app/controllers/application_controller.rb 5 3: layout :set_layout 6 4: private 7 5: def set_layout 8 6: if params[:controller].match(%r{\A(staff|admin|customer)/}) 9 7: byebug 10=> 8: Regexp.last_match[1] 11 9: else 12 10: "customer" 13 11: end 14 12: end 15(byebug) params[:controller] 16"staff/top" 17nil 18

試したこと2

#####ブラウザを変えてみた

chrome とfirefoxそれぞれで試しましたが結果は同じでした・・・。

補足情報(FW/ツールのバージョンなど)

windows10

virtualbox 6.1.12

ubuntu 20.04 LTS (Focal Fossa)"

docker 19.03.12

docker-compose version 1.25.0

###参考書籍
『Ruby on Rails 6 実践ガイド』の第5章までの内容を入力しています。
※書籍ではerbですがslimに変更しました。

###github・その他のソースコード
上記書籍のソースコードです。(erb以外はそのまま入力しています。)
5章までの内容ですので、ブランチは gamma-ch05 です。

https://github.com/kuroda/baukis2/tree/gamma-ch05

###上記書籍の正誤表です。
下記を参考に私の入力したコードも修正しています。
https://www.oiax.jp/books/jissen_rails6_errata

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

Ref: https://railsguides.jp/action_controller_overview.html#ルーティングパラメータ

paramsハッシュに必ず含まれるキーは:controllerキーと:actionキーです。ただしこれらの値には直接アクセスせず、controller_nameとaction_nameという専用のメソッドを使ってください。

関係ないかもしれませんが、 params[:controller] ではなく controller_name を利用するように推奨されています

Ref: https://railsguides.jp/layouts_and_rendering.html#レイアウトの探索順序

class ProductsController < ApplicationController layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" } end

のように、 layout フックは controller をパラメータとして渡すようなので、

layout :set_layout private def set_layout(controller) if controller.class_name.underscore.match(%r{\A(staff|admin|customer)/}) Regexp.last_match[1] else "customer" end end

例えば????のような形でいかがでしょう

投稿2020/07/24 16:24

編集2020/07/24 16:25
unhappychoice

総合スコア1531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DelphiumG

2020/07/25 07:06 編集

ありがとうございます!!!!!!  光の見えない真っ暗なトンネルで明るい出口を示していただいたような、感謝しかない思いです。 ####一部訂正 ただ、例示いただいたコードそのままではエラーが発生しましたので、いただいたアドバイスを もとに、若干手直ししたところ、見事エラー解消しました!!! (そのコードは自己解決欄に記載いたします) 本当にありがとうございました!!! やはりRailsGuide等のドキュメントを読むことも大事ですね。 また、一人で悩むのではなく賢人に教えを乞うのも本当に大事だと思いました。
guest

0

###一部修正しました(2)

今回のようにnamespace使用時にcontroller_nameでは"top"のみが返るのでnamespaceまで取得できるようにcontroller_pathに変更しました。
この場合underscoreも不要になりますので削除いたしました。

(原因)
コントローラの名前はcontroller_name で取得できますが namespace までは取得できないので、Staff::TopController の場合も Admin::TopController の場合も同じ top が返ってくる。

(訂正後)

class ApplicationController < ActionController::Base layout :set_layout private def set_layout if controller_path.match(%r{\A(staff|admin|customer)/})#訂正箇所 Regexp.last_match[1] else "customer" end end end

投稿2020/07/25 02:16

編集2020/07/25 07:08
DelphiumG

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

####一部修正しました(1)

unhappychoice様に頂いたコードそのままでは下記のエラーが発生いたしましたため

イメージ説明

unhappychoice様のアドバイスを元に、下記のように変更したところエラー解消しました。

※contorollerが引数として未定義エラーとのことでしたので、
controller_nameメソッド?に変更いたしました。

layout :set_layout private def set_layout if controller_name.underscore.match(%r{\A(staff|admin|customer)/}) Regexp.last_match[1] else "customer" end end

投稿2020/07/25 02:10

編集2020/07/25 07:09
DelphiumG

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問