我有一种情况,在CallbackController上调用一个动作。我无法控制这一点,因为它是由框架规定的。为了响应此操作,我需要创建一个新的身份验证。我的AuthenticationController具有创建和销毁操作。
我该怎么办?在我看来,我的选择是:
这些似乎都不是正确的答案。那么有人可以提出更好的方法吗?
我的回调控制器:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
authorize
end
def twitter
authorize
end
private
def authorize
omniauth_data = request.env["omniauth.auth"]
#Check to see if we have an authentication for this provider already
authentication = Authentication.find_by_provider_and_uid(omniauth_data['provider'], omniauth_data['uid'])
#If an authentication already exists, sign its User in
#Otherwise create a new authentication for the current user
if authentication
flash[:notice] = "Signed in successfully with " + omniauth_data['provider']
sign_in_and_redirect(:user, authentication.user)
elsif current_user
current_user.authentications.create(:provider => omniauth_data['provider'], :uid => omniauth_data['uid'])
flash[:notice] = "Authentication successful"
redirect_to user_profile_url
else
user = User.new
user.apply_omniauth_data_as_authentication(omniauth_data)
if user.save
flash[:notice] = "Signed in successfully with " + omniauth_data['provider']
sign_in_and_redirect(:user, authentication.user)
else
#save the omniauth data in a session so we can add the authentication once registration is complete
session[:omniauth] = omniauth_data.except('extra')
redirect_to new_user_registration_url
end
end
end
end
和我的身份验证控制器:
class AuthenticationsController < ApplicationController
#Controller for representing Authentications provided by
def index
current_user.authentications if current_user
end
def create
end
def destroy
@authentication = Authentication.find(params[:id])
provider = @authentication.provider
@authentication.destroy
flash[:notice] = "Destroyed authentication from "+provider
redirect_to authentications_url
end
end
答案 0 :(得分:2)
如果您控制CallbackController和AuthenticationController的代码(它们不是来自框架),您可以将公共代码拉出到一个公共超类中。或者只是将其放在module
和include
中。
我不是将整个create
和destroy
方法剪切并粘贴到一个新模块中,而是倾向于找到更小,连贯的部分并将它们放在具有有意义名称的方法中。可能是CallbackController和AuthenticationController上的create
和destroy
方法可以使用那些较小的方法在2行或3行中实现。
如果将相关的线组拉出到较小的方法中,您可以考虑将这些方法添加为ActionController::Base
的扩展名(如果合适的话)。 (即如果它们足够通用。)如果小方法在应用程序的其他部分有用,那就是奖励。