Help us understand the problem. What is going on with this article?

Rails(5)namespace でファイルを分ける方法

More than 1 year has passed since last update.

はじめに

1つのRailsアプリケーションの内で、管理画面のコードをadminみたいなネームスペースでわけて管理する事がありました。
その際の事を忘れないようにメモ。
今回ネームスペースで分けるのは以下の3つです。
adminstaffparticipant

※名前は適当なので、ご勘弁ください。

環境
Rails 5.1.3
Ruby 2.4.0

viewに各ネームスペースのディレクトリの作成

以下のディレクトリを作成
./app/views/admin
./app/views/staff
./app/views/participant

layoutsディレクトリ内に各ネームスペースのディレクトリを作成

以下のディレクトリを作成
./app/views/layouts/admin
./app/views/layouts/staff
./app/views/layouts/participant

layoutsディレクトリ内に各ネームスペースのhtml.erbを作成する

./app/views/layouts/admin.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>namespace - admin</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
<body>
<% content_for :content do %>  
  <%= yield %>
<% end %>
<%= render template: "layouts/application" %>
</body>
</html>

他もそれぞれつくる
./app/views/layouts/staff.html.erb
./app/views/layouts/participant.html.erb

controllerに各ネームスペースのディレクトリの作成

./app/controllers/admin
./app/controllers/staff
./app/controllers/participant

各ネームスペースのcontrollerのフォルダ内でbase.rbを作成

./app/controllers/admin/base.rb
class Admin::Base < ApplicationController
     layout 'admin'
end

application.html.erbを修正

application.htmlファイル全部を以下に書き換える

./app/views/layouts/application.html.erb
<%= content_for?(:content) ? yield(:content) : yield %>

試しにコントローラを作ってみる

rails generate controller admin/TestAdmin new
create  app/controllers/admin/test_admin_controller.rb
       route  namespace :admin do
    get 'test_admin/new'
  end
      invoke  erb
      create    app/views/admin/test_admin
      create    app/views/admin/test_admin/new.html.erb
      invoke  test_unit
      create    test/controllers/admin/test_admin_controller_test.rb
      invoke  helper
      create    app/helpers/admin/test_admin_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/admin/test_admin.coffee
      invoke    scss
      create      app/assets/stylesheets/admin/test_admin.scss

他もそれぞれつくる

rails generate controller staff/TestStaff new
rails generate controller participant/TestParticipant new

root.rbがネームスペースでルーティングされている事を確認

./config/routes.rb
  namespace :admin do
    get 'test_admin/new'
  end

作成したコントローラーの修正

base.rbを継承させるように修正する

./app/controllers/admin/test_admin_controller.rb
class Admin::TestAdminController < ApplicationController
  def new
  end
end

./app/controllers/admin/test_admin_controller.rb
class Admin::TestAdminController < Admin::Base
  def new
  end
end

他のコントローラも修正
./app/controllers/participant/test_participant_controller.rb
./app/controllers/staff/test_staff_controller.rb

ブラウザで表示の確認

/admin/test_admin/new
admin_test.png

/staff/test_staff/new
staff_test.png

/participant/test_participant/new
participant_test.png

各ネームスペース毎にheaderとfooterを設定する

_header.html.erbと_footer.html.erbの準備をする

以下のようにheaderとfooterの部分テンプレート作成する

./app/views/layouts/admin/_header.html.erb
<header>
  <p>admin_header</p>
</header>
./app/views/layouts/admin/_footer.html.erb
<footer>
  <p>admin_footer</p>
</footer>

他のそれぞれ作る
./app/views/layouts/staff/header.html.erb
./app/views/layouts/staff/
footer.html.erb

./app/views/layouts/participant/header.html.erb
./app/views/layouts/participant/
footer.html.erb

_header.html.erbと_footer.html.erbを呼び出す

./app/views/layouts/admin.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>namespace - admin</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
<body>
<% content_for :content do %>
  <%= render 'layouts/admin/header' %>
  <%= yield %>
  <%= render 'layouts/admin/footer' %>
<% end %>
<%= render template: "layouts/application" %>
</body>
</html>

他もそれぞれ呼び出す
./app/views/layouts/staff.html.erb
./app/views/layouts/participant.html.erb

ブラウザで確認

/admin/test_admin/new
admin_header_footer.png

/staff/test_staff/new
staff_header_footer.png

/participant/test_participant/new
participant_header_footer.png

CSSの振り分けを行う

cssファイルの作成

application.cssとは別にadmin.cssを以下のように作成してください

./app/assets/stylesheets/admin.css
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree ./admin
 */

他もそれぞれcssファイルを作ります。

.app/assets/stylesheets/staff.css
*= require_tree ./staff
./app/assets/stylesheets/participant.css
*= require_tree ./participant

作成したcssファイルをアセットプリコンパイルの対象に加える

以下のように追加

./config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( admin.css )
Rails.application.config.assets.precompile += %w( staff.css )
Rails.application.config.assets.precompile += %w( participant.css )

それぞれのネームスペース毎にスタイルを適用させる

スタイルリンクタグを修正

./app/views/layouts/admin.html.erb
<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>

./app/views/layouts/admin.html.erb
<%= stylesheet_link_tag    'admin', media: 'all', 'data-turbolinks-track': 'reload' %>

他もそれぞれ修正

./app/views/layouts/staff.html.erb
./app/views/layouts/participant.html.erb

スタイルを適用してみる

今回は、以下のように実験してみました

./app/assets/stylesheets/admin/test_admin.scss
body {
  background: red;
}
.app/assets/stylesheets/staff/test_staff.scss
body {
  background: green;
}
./app/assets/stylesheets/participant/test_participant.scss
body {
  background: blue;
}

ブラウザで確認

/admin/test_admin/new
admin_asset.png

/staff/test_staff/new
staff_asset.png

/participant/test_participant/new
participant_asset.png

サーバーを一度再起動せずに、アクセスすると以下のようなエラーが画面が表示されます。
その際は、サーバーを再起動してください。
asset_error.png

共通のスタイルなど

全体の設定など、共通のスタイルを当てる場合は以下のようにしています。

./app/assets/stylesheets/public/test_public.scss
header {
  background: yellow;
}

を作り

./app/assets/stylesheets/admin.css
*= require_tree ./public

のようにそれぞれのcssを修正

/admin/test_admin/new
admin_public.png

/staff/test_staff/new
staff_public.png

/participant/test_participant/new
participant_public.png

Jsファイルの振り分けを行う

jsファイルの作成

application.jsとは別にadmin.jsを以下のように作成してください

./app/assets/javascripts/admin.js
//= require rails-ujs
//= require turbolinks
//= require_tree ./admin

他もそれぞれjsファイルを作ります。

./app/assets/javascripts/staff.js
//= require_tree ./staff
./app/assets/javascripts/participant.js
//= require_tree ./participant

作成したjsファイルをアセットプリコンパイルの対象に加える

以下のように追加

./config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.precompile += %w( staff.js staff.css )
Rails.application.config.assets.precompile += %w( participant.js participant.css )

それぞれのネームスペース毎にJSを適用させる

JSインクルードタグを修正

./app/views/layouts/admin.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

./app/views/layouts/admin.html.erb
<%= javascript_include_tag 'admin', 'data-turbolinks-track': 'reload' %>

他もそれぞれ修正

./app/views/layouts/staff.html.erb
./app/views/layouts/participant.html.erb

JSを適用してみる

今回は、以下のように実験してみました

./app/assets/javascripts/admin/test_admin.coffee
alert 'admin'
./app/assets/javascripts/staff/test_staff.coffee
alert 'staff'
./app/assets/javascripts/participant/test_participant.coffee
alert 'participant'

ブラウザで確認

/admin/test_admin/new
admin_js.png

/staff/test_staff/new
staff_js.png

/participant/test_participant/new
participant_js.png

サーバーを一度再起動せずに、アクセスすると以下のようなエラーが画面が表示されます。
その際は、サーバーを再起動してください。
asset_js_error.png

終わりに

以上が、Rails(5)namespaceでディレクトリで分ける方法になります。
勉強不足で、このやり方が最適な方法か否かはわかりません。
もし、もっといい方法知ってる方いらっしゃいましたらぜひコメント等で教えてください。

maggam
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした