地方でリモートワーク in Iwate

東京の受託開発会社でリモートワークしてます。

deviseで2つのモデルを管理しつつ、usersリソースをdeviseとdevise以外で管理したいときの実装方法

スポンサーリンク

f:id:ihatov08:20160916231952j:plain

deviseのちょっと応用の使い方です。

deviseで複数モデルを管理するときのルーティング

deviseで2つのモデルを管理するときはたいてい以下のようなルーティングを設定すると思います。

# routes.rb

  devise_for :users, :controllers => {
      :sessions           => 'admin_users/sessions',
      :passwords          => 'admin_users/passwords',
      :registrations      => 'admin_users/registrations',
  }

  devise_for :admin_users, :controllers => {
      :sessions           => 'admin_users/sessions',
      :passwords          => 'admin_users/passwords',
      :registrations      => 'admin_users/registrations',
  }

上記ルーティングの問題点

この場合、userのsignup(registrations#create)のpostのパスが/usersです。 devise以外でcreateとupdateをしようとして

resouces :users

と記述してもpostのパスが/usersでかぶってしまいます。 ルーティングは上から読み込まれるので、上に書いた方のパスにpostされます。

devise以外でcreate,updateできない

devise以外でcreateとupdateが上記パスだとパスが被ってしまうためできないです。 views/users/new.html.erbでform_forでpostしてもなぜかdeviseを通っていて、logを見てみたら判明しました。

www.tom08.net

解決方法

deviseのルーティングのオプションを使います。skipオプションを使うとdeviseで生成される標準のルーティングを生成しないことができます。 その上でresouces :usersなどと被らないパスを設定してあげればOKです。

  devise_for :users, skip: [:sessions, :passwords, :registrations ]
  devise_scope :user do
    get  'users/sign_up' => 'users/registrations#new'
    post 'users/create' => 'users/registrations#create'
  end

パスワードの扱い

deviseのcontrollerクラスを通さなくても、devise管理であることをモデルに記述していれば、postでパスワードを暗号化してくれます。つまり普通にpostしてあげればOKです。

registrations#create

本当はadmin_userでuserの追加をusers/registrations#createでできればよかったのですが、createするとsign inもしてしまってユーザーの連続作成ができませんでした。(できる方法ないかなー)