読者です 読者をやめる 読者になる 読者になる

めも帖

「めも帖」代わりにダラダラと書いていったり、めもしたりしているだけです。

Rails 3.2で管理者向けのURLを用意してみた

ウェブサイトを作るとき、閲覧向けと、管理者向けの二種類のサイトをまとめて1つのサイトとなることが多いです(管理者向けも、さらにサービス管理とか、コンテンツ投入者など細分化されるかもしれません)。
そんなとき、URLを分けて管理したくなります。

目的のURL構成

閲覧用には、index、showだけ

管理用は、すべて用意

新しいアプリケーションを用意お決まりで(後から見たら、カラム名が間違えていましたけれど)

$ rails new test
$ cd test
$ rails generate scaffold Post ttile:string body:text
$ rake db:migrate

ルーティング

今回の肝。

  • config/routes.rb
  • namespaceを使ってみました
  • 閲覧者用は、resourcesですが、:onlyで制限を加えています
  namespace :admin do
       resources :posts
  end

  resources :posts, :only=>[:index, :show]|
ルーティングのテスト

ルーティングを確認してみました

$ rake routes
    admin_posts GET    /admin/posts(.:format)          admin/posts#index
                POST   /admin/posts(.:format)          admin/posts#create
 new_admin_post GET    /admin/posts/new(.:format)      admin/posts#new
edit_admin_post GET    /admin/posts/:id/edit(.:format) admin/posts#edit
     admin_post GET    /admin/posts/:id(.:format)      admin/posts#show
                PUT    /admin/posts/:id(.:format)      admin/posts#update
                DELETE /admin/posts/:id(.:format)      admin/posts#destroy
          posts GET    /posts(.:format)                posts#index
           post GET    /posts/:id(.:format)            posts#show

コントローラーを用意

管理者用のコントローラーの親
  • app/controllers/admin_controller.rb
class AdminController < ActionController::Base
  protect_from_forgery
end
管理者用のコントローラーの子
  • app/controllers/admin/posts_controller.rb
  • クラス名に注意
class Admin::PostsController < AdminController|
# 中身は、app/controllers/posts_controller.rbからコピー
end

ちなみに、クラスを分けたのは、

  • 管理者用のテンプレートファイルを用意したかった
  • 管理者用は、ユーザー管理下に入ると思うから閲覧用途は別の親クラスがあったほうが良さそう
閲覧者用のコントローラー
  • app/controllers/posts_controller.rb
class PostsController < ApplicationController  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @post }
    end
  end
end

テンプレート

  • views/admin/posts/index.html.erb
    • views/posts/ 以下を基本は、コピー
  • link_to の部分を変更。ヘルパーで用意されるものが変わっています
<h1>Admin Listing posts</h1>

<%= link_to 'INDEX', admin_posts_path %>

<table>
  <tr>
    <th>Ttile</th>
    <th>Body</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @posts.each do |post| %>
  <tr>
    <td><%= post.ttile %></td>
    <td><%= post.body %></td>
    <td><%= link_to 'Show', admin_post_path(post) %></td>
    <td><%= link_to 'Edit', edit_admin_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Post', new_admin_post_path %>
レイアウト

管理者用のレイアウトファイルを用意

  • views/layouts/admin.html.erb
<!DOCTYPE html>
<html>
<head>
  <title>Admin Test3</title>
  <%= stylesheet_link_tag    "application", :media => "all" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>