Rails deviseでアカウント情報を更新するとactiveadminの閲覧画面の内容が全て同じになる
activeadminの管理画面でUserの一覧画面(index)から閲覧(show)をクリックするとどのユーザの閲覧もユーザid2の情報が表示されてしまいます。
現象はアカウント情報を変更すると起きます。
例: Twitter認証後にメールアドレス、ユーザネーム、パスワードを一度に変更した時に現象が起きます。
ログ
Started GET "/admin/users/1" for 127.0.0.1 at 2015-06-11 02:33:01 +0900
Processing by Admin::UsersController#show as HTML
Parameters: {"id"=>"1"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
AdminUser Load (0.2ms) SELECT "admin_users".* FROM "admin_users" WHERE "admin_users"."id" = ? ORDER BY "admin_users"."id" ASC LIMIT 1 [["id", 1]]
(0.1ms) SELECT COUNT(*) FROM "active_admin_comments" WHERE "active_admin_comments"."resource_type" = ? AND "active_admin_comments"."resource_id" = ? AND "active_admin_comments"."namespace" = ? [["resource_type", "User"], ["resource_id", "2"], ["namespace", "admin"]]
CACHE (0.0ms) SELECT COUNT(*) FROM "active_admin_comments" WHERE "active_admin_comments"."resource_type" = ? AND "active_admin_comments"."resource_id" = ? AND "active_admin_comments"."namespace" = ? [["resource_type", "User"], ["resource_id", "2"], ["namespace", "admin"]]
Rendered /Users/mai/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/bundler/gems/active_admin-cef68b7be826/app/views/active_admin/resource/show.html.arb (408.3ms)
コントローラー
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
callback_from :facebook
end
def twitter
callback_from :twitter
end
private
def callback_from(provider)
provider = provider.to_s
@user = User.find_for_oauth(request.env['omniauth.auth'])
@user.skip_confirmation!
if @user.persisted?
flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
sign_in_and_redirect @user, event: :authentication
else
if provider == 'twitter'
session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
end
redirect_to new_user_registration_url
end
end
class Users::RegistrationsController < Devise::RegistrationsController
protected
# 現在のパスワードを入力せずにアカウント情報を変更
def update_resource(resource, params)
resource.update_without_current_password(params)
end
モデル
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :authentication_keys => [:login]
attr_accessor :login
# 現在のパスワードを入力せずにアカウント情報を変更
def update_without_current_password(params, *options)
params.delete(:current_password)
if params[:password].blank? && params[:password_confirmation].blank?
params.delete(:password)
params.delete(:password_confirmation)
end
result = update_attributes(params, *options)
clean_up_passwords
result
end
def self.find_for_oauth(auth)
user = User.where(uid: auth.uid, provider: auth.provider).first
unless user
user = User.create(
uid: auth.uid,
name: auth.info.name,
user_name: User.dummy_user_name(auth),
provider: auth.provider,
email: User.dummy_email(auth),
password: Devise.friendly_token[0, 20]
)
end
user
end
private
def self.dummy_email(auth)
if auth.info.email.blank?
"#{auth.uid}-#{auth.provider}@example.com"
else
auth.info.email
end
end
def self.dummy_user_name(auth)
if auth.info.user_name.blank?
"#{Random.rand(1..9999)}#{auth.provider}#{auth.uid}"
else
auth.info.nickname
end
end
# Deviseでメールアドレス以外のカラムをログイン認証に利用
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_h).where(["lower(user_name) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions.to_h).first
end
end
validates :user_name,
:uniqueness => {
:case_sensitive => false
},
:format => { with: /\A[a-z0-9]+\z/i },
:length => { maximum: 40 }
def self.current_user=(user)
Thread.current[:current_user] = user
end
end
routes.rb
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
#devise_for :users, param: :id_name, :controllers => {:omniauth_callbacks => "users/omniauth_callbacks"}
# devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
devise_for :users, :controllers => {
:omniauth_callbacks => 'users/omniauth_callbacks',
:registrations => 'users/registrations',
:sessions => 'users/sessions'
}