aasmの使い方が解った気がした、36の夜。

じゃあ、とりあえず、Usersコントローラを、適切な感じで、バラして別けていきましょうかね。

で、ユーザ管理機能は、Admin以下に移すことにしましょう。

まず、controllerのジェネレート。

$ script/generate controller Admin::Users index edit

んで、以前のusers_controller.rbから、ごそっとコピペして、切ったり張ったり。
以下のように生まれ変わりました。
app/controllers/admin/users_controller.rb

class Admin::UsersController < ApplicationController
  require_role(APP_CONFIG["role"]["administrator"])

  def index
    @users = User.find(:all)
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      flash[:notice] = "User updated"
      redirect_to(admin_users_path)
    else
      render(:action => 'edit')
    end
  end

  def activate
    @user = User.find(params[:id])
    if @user.activate!
      flash[:notice] = "User \"#{@user.nickname}\" was activated!"
    else
      flash[:notice] = "There was a problem activating this user"
    end
    redirect_to(admin_users_path)
  end

  def pend
    @user = User.find(params[:id])
    if @user.pend!
      flash[:notice] = "User \"#{@user.nickname}\" was Pended!"
    else
      flash[:notice] = "There was a problem pending User \"#{@user.nickname}\""
    end
    redirect_to(admin_users_path)
  end

  def suspend
    @user = User.find(params[:id])
    if @user.suspend! 
      flash[:notice] = "User \"#{@user.nickname}\" was Suspended!"
    else
      flash[:notice] = "There was a problem suspending User \"#{@user.nickname}\""
    end
    redirect_to(admin_users_path)
  end

  def unsuspend
    @user = User.find(params[:id])
    if @user.unsuspend!
      flash[:notice] = "User \"#{@user.nickname}\" was Unsuspended!"
    else
      flash[:notice] = "There was a problem unsuspending User \"#{@user.nickname}\""
    end
    redirect_to(admin_users_path)
  end

  def destroy
    @user = User.find(params[:id])
    if @user.delete!
      flash[:notice] = "User \"#{@user.nickname}\" was Deleted!"
    else
      flash[:notice] = "There was a problem Deleted User \"#{@user.nickname}\""
    end
    redirect_to(admin_users_path)
  end

  def purge
    @user = User.find(params[:id])
    @user.destroy
    redirect_to(admin_users_path)
  end
end

ん〜、多分、editとupdateは、後々いらなくなると思うんだよね。
もちろん、管理者側とユーザとで、変更出来る項目に差をつけなければいけないんだけど、でも、そんなのは、一つのコントローラ/ビューでやっちゃえばいい気がする。

んにゃ? ダメか?
roleで分岐するの、面倒臭そうだな...

まあ、いいやwww


そうそう。
それで。
ペロッとコピって、貼り付けて、コード見ていて、思いました。
「んっ? @user.activate!って、activate!メソッドって、どこにあるのよ?」

んで、探しに探しました。
どうも、これ、あれだよね?
aasmで、stateをセットしてるよね?
じゃあ、それ、どこでやってるのよ?

んで、「aasm」で、検索しました。
どうも、vendor/plugins/restful_authentication/lib/authorization/aasm_roles.rbが怪しい。

つうか、これでしょ?www

ということで、どうも、AasmRolesでは、stateをpendingにするeventはセットしていないようなので、セットした。

あと、stateがdeleteのユーザをactiveに出来るようにした。その結果が、下の通り。
vendor/plugins/restful_authentication/lib/authorization/aasm_roles.rb

         aasm_event :activate do
          transitions :from => :pending, :to => :active 
+          transitions :from => :deleted, :to => :active
         end
+
+        aasm_event :pend do
+          transitions :from => [:active, :deleted], :to => :pending
+        end
         
         aasm_event :suspend do

これで、ユーザ一覧から、ユーザのstateを変更出来るようになった筈。
つうか、テスト書けよ => 俺www

じゃあ、ビュー。
app/views/admin/users/_user.html.erb

<tr>
  <th>
    <%= user.id %>
  </th>
  <td>
    <%= link_to(user.nickname, user_path(user.id)) %>
  </td>
  <td>
    <%= user.email %>
  </td>
  <td>
    <%= user.full_name %>
  </td>
  <td>
    <% for role in user.roles %>
    <li>
      <%= link_to(role.name, admin_role_path(role.id)) %>
    </li>
    <% end %>
  </td>
  <td>
    <%= user.state %>
  </td>
  <td>
    <ul>
      <li>
        <%= link_to("Edit", edit_admin_user_path(user.id)) %>
      </li>
      <%- if user.state == "pending" || user.state == "deleted" -%>
      <li>
        <%= link_to("Activate", activate_admin_user_path(user.id), :method => :put) %>
      </li>
      <%- end -%>
      <%- if user.state == "active" || user.state == "deleted" -%>
      <li>
        <%= link_to("Pend", pend_admin_user_path(user.id), :method => :put) %>
      </li>
      <%- end -%>
      <%- if user.state == "passive" || user.state == "pending" || user.state == "active" -%>
      <li>
        <%= link_to("Suspend", suspend_admin_user_path(user.id), :method => :put) %>
      </li>
      <%- end -%>
      <%- if user.state == "suspended" -%>
      <li>
        <%= link_to("Unuspend", unsuspend_admin_user_path(user.id), :method => :put) %>
      </li>
      <%- end -%>
      <%- if user.state != "deleted" -%>
      <li>
        <%= link_to("Delete", admin_user_path(user.id), :method => :delete) %>
      </li>
      <%- end -%>
    </ul>
  </td>
</tr>

おっ、なんか、結構作り込んでるっぽいぞwww
珍しいねwwwwww

次。ユーザ一覧。
app/admin/users/index.html.erb

<table>
  <thead>
    <tr>
      <th>
        ID
      </th>
      <th>
        Nickname
      </th>
      <th>
        Email
      </th>
      <th>
        Full Name
      </th>
      <th>
        Role
      </th>
      <th>
        Status
      </th>
      <th>
        Action
      </th>
    </tr>
  </thead>
  <tbody>
<%= render(:partial => 'user', :collection => @users) %>
  </tbody>
</table>

んで、ユーザ編集。
これは、app/views/users/edit.html.erbをまるっとコピペ;-p
ホントは、ロールを付けたり消したりできるようにしないといけないよな...

まあ、ヨシwww
app/views/admin/users/edit.html.erb

<%= error_messages_for :user %>
 
<%- form_for(:user, :url => admin_user_path(@user), :html => { :method => :put }) do |f| -%>
  <dl>
    <dt>
      Nickname:
    </dt>
    <dd>
      <%= f.text_field(:nickname, :size => 60) %>
    </dd>
    <dt>
      Family_name
    </dt>
    <dd>
      <%= f.text_field(:family_name, :size => 60) %>
    </dd>
    <dt>
      middle_name
    </dt>
    <dd>
      <%= f.text_field(:middle_name, :size => 60) %>
    </dd>
    <dt>
      Given_name
    </dt>
    <dd>
      <%= f.text_field(:given_name, :size => 60) %>
    </dd>
  </dl>
<%= submit_tag('Save') %>
<%- end -%>

んで、ルーティングの変更。
config/routes.rb

   map.namespace :admin do |admin|
+    admin.resources :users, :member => {  :activate   =>  :put,
+                                          :pend    =>  :put,
+                                          :suspend    =>  :put,
+                                          :unsuspend  =>  :put,
+                                          :purge      =>  :delete }
     admin.resources :roles
   end
 
-  map.resources :users, :member => { :suspend   => :put,
-                                     :unsuspend => :put,
-                                     :purge     => :delete }
+  map.resources :users, :member => {  :activate   =>  :put,
+                                      :suspend    =>  :put,
+                                      :unsuspend  =>  :put,
+                                      :purge      =>  :delete }
+  map.resource :user
   map.resource :session
 
   # The priority is based upon order of creation: first created -> highest priority.

ああああああ、テスト、めんどくせぇーーーーーっ