This tutorial was in reference to issue wearefine/fae#302. This will assist you in setting up Fae with existing Devise or integrating with Devise Token Auth. This will continue using devise without losing functionality of Fae’s devise configurations. This issue exists because Devise only allows one parent controller for the whole library. This solution is not to be taken as best practices but solves the issue with the hand that was dealt.
Fae provides a set of controller actions that setup the look and feel for the layout and other custom configurations. In order to keep these before actions from running on your devise controllers, you can setup a controller to skip them. If you look at the source code here you will see that fae sets devise base controller as Fae::ApplicationController
. In order to keep these intact, you will have to create a controller that inherits that controller. Below is a snippet that will help you get started:
class ApplicationDeviseController < Fae::ApplicationController
skip_before_action :check_disabled_environment, if: -> { custom_devise_controller? }
skip_before_action :first_user_redirect, if: -> { custom_devise_controller? }
skip_before_action :authenticate_user!, if: -> { custom_devise_controller? }
skip_before_action :build_nav, if: -> { custom_devise_controller? }
skip_before_action :set_option, if: -> { custom_devise_controller?(['api']) }
skip_before_action :detect_cancellation, if: -> { custom_devise_controller? }
skip_before_action :set_change_user, if: -> { custom_devise_controller? }
skip_before_action :set_locale, if: -> { custom_devise_controller? }
protect_from_forgery prepend: true, if: Proc.new { |c| c.request.format.json? }
helper_method :custom_devise_controller?
def after_sign_in_path_for(_resource)
custom_devise_controller?(['customers']) ? edit_customer_registration_path : super
end
def after_sign_out_path_for(_resource)
custom_devise_controller?(['customers']) ? new_customer_session_path : super
end
private
def custom_devise_controller?(values = ['api', 'customers'])
values.include?(request.path[1..-1].split('/')[0])
end
end
This snippet above will skip a set of given before actions on requests paths that you specify. For example you will see there is a resource route called customers
and a namespace called api
that both use devise controllers. You will notice on :set_option
, there was an override for only api
paths as I re-used fae’s look and feel from devise for this project to same some time. That is up to you on how you want to handle that.
In order for the above controller to be used you will have to define the following in your devise.rb
initializer:
config.parent_controller = 'ApplicationDeviseController'
Next you will have issues regarding the views interpretating resource paths.
So for example, in this project I had a devise model called customers. So I suggest copying all devise views from here if you plan on using Fae’s look and feel. You will have to change all paths that are interprating resource name like the following example listed below:
views/customers/confirmations/new.html.slim
.login-form
h2 style="margin-bottom: 20px" Resend confirmation instructions
= simple_form_for(resource, :as => resource_name, :url => customer_confirmation_path, :html => { :method => :post }) do |f|
= f.error_notification
= f.full_error :confirmation_token
.form-inputs
= f.input :email, :required => true, :autofocus => true
.form-actions
= f.button :submit, "Resend confirmation instructions"
Notice that is customer_confirmation_path
is now an explicit path name instead of confirmation_path(resource_name)
. You will want to do this for the rest of the devise views and don’t forget the mailer views as well.
In addition, if you want these views to be scoped you have to change the devise.html.slim
layout to support that.
.login-helper == render "#{custom_devise_controller? ? devise_mapping.scoped_path : 'devise'}/shared/links" unless params[:controller] == 'fae/setup' || params[:controller] == 'devise/registrations'
This will interpolate shared links to be /customers/shared/links
instead of /devise/shared/links
.
If you want to use your own views instead of Fae’s look and feel, you will have to override the layout on your own devise controllers which can be done with layout 'my_custom_layout'
. Best of luck using Devise with Fae.