[Rails3] 管理画面とフロント画面のroutesの綺麗な分離方法

管理画面とフロント画面のroutesの綺麗な分離方法


RailsでWebアプリケーションを作成していると、当然ですが、フロント側の画面と管理用の画面の二種類ができてきます
その際に、フロント側からは当然ですが、管理用の画面を見せたくないという場面が出てくるかと思います
その場合、Apache等でIP制限をかけたりするなどの対策が考えられますが、Rails側で次のようにすることもできます


ほとんど同じですが、Routing部分をmoduleに切り出した方法をこちらに追記しました。
http://namakesugi.blog42.fc2.com/blog-entry-162.html


環境 Rails 3.1.1, Ruby 1.9.2


Rails.configurationとroutesを組み合わせた方法


アプリケーションは以下のようになっているとします


app/controllers
├── admin
│   └── books_controller.rb
├── application_controller.rb
└── front
└── books_controller.rb

ここでroutes.rbには以下のように定義されているとします


# coding: utf-8

RoutesTest::Application.routes.draw do
namespace :front do
resources :books, only: %w(index show)
end

namespace :admin do
resources :books, except: %w(show)
end
end

このままですと当然ですがrake routesの結果は以下のようになります


$ rake routes
front_books GET /front/books(.:format) {:action=>"index", :controller=>"front/books"}
front_book GET /front/books/:id(.:format) {:action=>"show", :controller=>"front/books"}
admin_books GET /admin/books(.:format) {:action=>"index", :controller=>"admin/books"}
POST /admin/books(.:format) {:action=>"create", :controller=>"admin/books"}
new_admin_book GET /admin/books/new(.:format) {:action=>"new", :controller=>"admin/books"}
edit_admin_book GET /admin/books/:id/edit(.:format) {:action=>"edit", :controller=>"admin/books"}
admin_book PUT /admin/books/:id(.:format) {:action=>"update", :controller=>"admin/books"}
DELETE /admin/books/:id(.:format) {:action=>"destroy", :controller=>"admin/books"}

このままで、なにもしないとfront側のWebサーバからadminへのroutingが提供されてしまい、
何かしらの手を打たないと危険な状態になってしまいます
通常であれば、Apacheなりで制御しますが、今回は以下のようにします


routes.rbの修正


routes.rbを以下のように修正します


# coding: utf-8

RoutesTest::Application.routes.draw do
namespace :front do
resources :books, only: %w(index show)
end

namespace :admin do
resources :books, except: %w(show)
end if Rails.configuration.admin_enable
end

Railsの設定中でadmin_enableがtrueでないと、namespace :adminが実行されないようにします


application.rbに以下を追加します


module RoutesTest
class Application < Rails::Application
# ... 略
config.admin_enable = true
end
end

次にenviroments/production.rbをコピーしてadmin用のenvironmentを用意します


cp config/environments/production.rb config/environments/admin_production.rb

最後にproduction.rb (front用のenvironment)に以下を追加します


# coding: utf-8
RoutesTest::Application.configure do
config.admin_enable = false
end

この状態で、rake routesを各environmentで実行すると以下のようになります


$ rake routes RAILS_ENV=production
front_books GET /front/books(.:format) {:action=>"index", :controller=>"front/books"}
front_book GET /front/books/:id(.:format) {:action=>"show", :controller=>"front/books"}
$ rake routes RAILS_ENV=admin_production
front_books GET /front/books(.:format) {:action=>"index", :controller=>"front/books"}
front_book GET /front/books/:id(.:format) {:action=>"show", :controller=>"front/books"}
admin_books GET /admin/books(.:format) {:action=>"index", :controller=>"admin/books"}
POST /admin/books(.:format) {:action=>"create", :controller=>"admin/books"}
new_admin_book GET /admin/books/new(.:format) {:action=>"new", :controller=>"admin/books"}
edit_admin_book GET /admin/books/:id/edit(.:format) {:action=>"edit", :controller=>"admin/books"}
admin_book PUT /admin/books/:id(.:format) {:action=>"update", :controller=>"admin/books"}
DELETE /admin/books/:id(.:format) {:action=>"destroy", :controller=>"admin/books"}

これで、フロント側からadmin側へアクセスできなくなりました
若干ですが、Railsの起動コスト等も減るはずです
※新たなENVを切ったので、database.ymlも追加するのを忘れないで下さい


さらにさらにの小技 prefixを変更する


こうなると今度は/adminでアクセスするのが嫌になってきます
せっかくadmin.example.comというサブドメインを管理用できったのに
admin.example.com/adminでアクセスするなんて煩わしいですよね
ということで以下のようにroutesを修正します


# coding: utf-8

RoutesTest::Application.routes.draw do
namespace :front do
resources :books, only: %w(index show)
end

namespace :admin, path: Rails.configuration.admin_route_prefix do
resources :books, except: %w(show)
end if Rails.configuration.admin_enable
end

namespace :adminにpathという値を追加しました
この状態で、application.rbに以下を追加します


module RoutesTest
class Application < Rails::Application
# ... 略
config.admin_route_prefix = "/admin"
end
end

次に管理画面用のenviromentであるadmin_environment.rbに以下を追加します


# coding: utf-8
RoutesTest::Application.configure do
# ... 略
config.admin_route_prefix = "/"
end

この状態でrake routes RAILS_ENV=admin_productionを実行すると以下のようになります


$ rake routes RAILS_ENV=admin_production
front_books GET /front/books(.:format) {:action=>"index", :controller=>"front/books"}
front_book GET /front/books/:id(.:format) {:action=>"show", :controller=>"front/books"}
admin_books GET /books(.:format) {:action=>"index", :controller=>"admin/books"}
POST /books(.:format) {:action=>"create", :controller=>"admin/books"}
new_admin_book GET /books/new(.:format) {:action=>"new", :controller=>"admin/books"}
edit_admin_book GET /books/:id/edit(.:format) {:action=>"edit", :controller=>"admin/books"}
admin_book PUT /books/:id(.:format) {:action=>"update", :controller=>"admin/books"}
DELETE /books/:id(.:format) {:action=>"destroy", :controller=>"admin/books"}

/admin/booksではなく、/booksで始まるようになりました


front側もnamespaceを切ったのはこういう理由で同様にしてpathを追加してあげることで任意の場所から開始できるようになります
当然、テストへの影響はほとんどないため、ほぼノーリスク(きちんとadmin_book_path等で遷移が実装できていれば)でRailsのルーティングを自由に操作できるようになります

スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。