rails2.Xでscaffoldで/admin/usersとかのコントローラ作りたいとき

rails2でscaffoldすると、migrateも作られるようになったのはわかった。
で、usersがある状態で/admin/usersみたいな会員管理コントローラを作りたいとき。

#いや、管理ページはRestfullにする必要ないかもしれないけど。。/mypage/xxxとかありうると思うから

scaffold

$ script/generate scaffold Admin::user --skip-migration
      create  app/models/admin
      create  app/controllers/admin
      create  app/helpers/admin
      create  app/views/admin/users
      create  app/views/layouts/admin
      create  test/functional/admin
      create  test/unit/admin
      create  app/views/admin/users/index.html.erb
      create  app/views/admin/users/show.html.erb
      create  app/views/admin/users/new.html.erb
      create  app/views/admin/users/edit.html.erb
      create  app/views/layouts/admin/users.html.erb
   identical  public/stylesheets/scaffold.css
  dependency  model
      exists    app/models/admin
      exists    test/unit/admin
      create    test/fixtures/admin
      create    app/models/admin/user.rb
      create    test/unit/admin/user_test.rb
      create    test/fixtures/admin_users.yml
      create  app/controllers/admin/users_controller.rb
      create  test/functional/admin/users_controller_test.rb
      create  app/helpers/admin/users_helper.rb
       route  map.resources :users

で、localhost:3000/admin/usersにアクセスすると

 NoMethodError in Admin/users#index

Showing admin/users/index.html.erb where line #7 raised:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

Extracted source (around line #7):

4:   <tr>
5:   </tr>
6: 
7: <% for user in @users %>
8:   <tr>
9:     <td><%= link_to 'Show', user %></td>
10:     <td><%= link_to 'Edit', edit_user_path(user) %></td>

/admin/user/index.html.erbの7行目に文句言われる

<% for user in @users %>

コントローラーを見ると

  def index
    @admin_users = Admin::User.find(:all)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @admin_users }
    end
  end

indexメソットだけ@admin_usersになってるので@usersに戻す。

view直す

<%= link_to 'New user', new_user_path %>

は多分:name_prefix=adminということだから

<%= link_to 'New user', new_admin_user_path %>

xmlの整形でコケル

admin/users.xmlとかでエラーになる

users = Admin::User.find(:all)
#中略
format.xml  { render :xml => @users }

だと

#<Admin::User id: 1, name: "hogehoge", created_at: "2008-02-12 23:14:05"(略)

インスタンスからxmlをパースしようとして

<admin/usre id:(略

みたいにしてパースエラーになるのでAdmin::Userモデルはクビでいいと思う。
そもそも同じスキーマに複数モデルがあったらきっと美しくない気がしてきた。
ので、Admin::User.newとかを全部User.newとかにする。

たぶん

これで、ふつーのscaffoldした感じと同じになる気がする。

つまり/admin以下にコントローラを作る場合

  • scaffoldする
  • route.rbにnamespace書く
  • 生成されたcontorollerの
    • indexの@admin_usersを@usersにする
    • Admin::Users.new等をUsers.newにする
    • /models/admin/user.rbを消す
  • 生成されたviewの
    • migrationをskipしてるのでスキーマ情報がないので書く
    • new_user_pathとかをnew_admin_user_pathとかに書き換える

くらいでおkかな。
全部試してないけど。