Связь между контроллерами в Rails - PullRequest
1 голос
/ 25 января 2012

У меня есть ситуация, когда на CallbackController вызывается действие.Я не имею никакого контроля над этим, поскольку это предписано структурой.В ответ на это действие мне нужно создать новую аутентификацию.Мой AuthenticationController имеет действия создания и уничтожения.

Как мне действовать?Мне кажется, у меня есть варианты:

  1. Дублировать код из действия create AuthenticationCOntroller в мой CallbackController (очевидно, далеко от DRY)
  2. Вызвать метод create непосредственно из CallbackController (такогомежконтроллерного взаимодействия, кажется, хмурится)
  3. Разбейте код из действия создания 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

1 Ответ

2 голосов
/ 25 января 2012

Если вы управляете кодом как для CallbackController, так и AuthenticationController (они не исходят из фреймворка), вы можете вытащить общий код из общего суперкласса. Или просто поместите его в module и include it.

Вместо того, чтобы вырезать и вставить все методы create и destroy в новый Модуль, я был бы склонен находить меньшие, согласованные части и помещать их в методы со значимыми именами. Может случиться так, что методы create и destroy в CallbackController и AuthenticationController могут быть реализованы всего за 2 или 3 строки с использованием этих меньших методов.

Если вы вытягиваете когерентные группы линий в меньшие методы, вы можете рассмотреть возможность добавления этих методов в качестве расширения к ActionController::Base, если это кажется целесообразным. (т.е. если они достаточно общие.) Если маленькие методы полезны в других частях приложения, это бонус.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...