layout diverso per l'azione di accesso in devise


84

Sto cercando di utilizzare un layout diverso / personalizzato denominato "devise" per l'azione sign_in. Ho trovato questa pagina nel wiki di devise, e il secondo esempio dice anche che puoi farlo per azione (in questo caso, sign_inazione), ma non mostra alcun esempio di ciò. Qualcuno su IRC mi ha detto che potevo provare questo:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout :layout_by_resource

  def layout_by_resource
    if devise_controller? && resource_name == :user && action_name == 'sign_in'
      "devise"
    else
      "application"
    end
  end
end

Ma non sembra funzionare poiché sta ancora caricando il layout dell'applicazione predefinito. Gradirei qualsiasi aiuto.

Risposte:


96

Un altro modo per applicare il layout personalizzato per un'azione è il seguente.

Secondo How To: Creare layout personalizzati "Puoi anche impostare il layout per controller Devise specifici utilizzando un callback in config / environment.rb (rails 2) o config / application.rb (rails 3). Questo deve essere fatto in un to_prepare callback perché viene eseguito una volta in produzione e prima di ogni richiesta in fase di sviluppo. "

config.to_prepare do
    Devise::SessionsController.layout "devise"
    Devise::RegistrationsController.layout proc{ |controller| user_signed_in? ? "application"   : "devise" }
    Devise::ConfirmationsController.layout "devise"
    Devise::UnlocksController.layout "devise"            
    Devise::PasswordsController.layout "devise"        
end

Di solito viene fatta una distinzione di layout tra le pagine dietro il login e le pagine che non richiedono l'autenticazione, quindi l'approccio di cui sopra funziona la maggior parte del tempo. Ma ho anche sperimentato l'utilizzo di action_namehelper per impostare un layout per un'azione particolare e ha funzionato a meraviglia:

config.to_prepare do
    Devise::SessionsController.layout proc{ |controller| action_name == 'new' ? "devise"   : "application" }
end

Penso che questo sia il modo migliore e costruito per cambiare il layout in base a devise controller / action invece di creare un helper in ApplicationController.


3
Inoltre, non dimenticare di riavviare il server ogni volta che apporti una modifica a qualsiasi file nella cartella config, in questo caso config / application.rb per Rails3 o config / environment.rb per Rails 2, affinché le modifiche abbiano effetto.
Zeeshan

Attenzione, ho provato questo metodo in rails 3.1 e rende il caricamento degli asset dalla cartella degli asset notevolmente più lento. Ciò non influirà sui server di produzione, ma quando hai più di pochi file css / js, lo noterai.
Gazler

nell'esempio sopra, è possibile configurare layout per risorse di devise separate (ad esempio, supponiamo di avere due diversi tipi di utenti di devise e ognuno ha bisogno del proprio layout)
ckarbass

Quando provo questo, ottengo un errore che ora sta cercando di ottenere un modello da due posizioni. Come fate in modo che Rails sovrascriva le impostazioni precedenti di Devise?
Adam Grant,

Per coloro che se lo sono perso - la configurazione di Rails 3 è diversa - fate questo in: config / application.rb (rails 3).
Stone

66

Ho appena creato app / views / layouts / devise / sessions.html.erb e ho inserito il mio layout lì.


28
Ottima soluzione! Puoi anche inserire un layout in /app/views/layouts/devise.html.erb e farlo applicare a tutte le tue viste di devise
Basti

45

L'ho capito, ma terrò questa domanda qui nel caso altre persone siano curiose.

È stato uno stupido errore. Il fatto è che sign_inè il percorso, non l'azione. Guardando la fonte pertinente , posso vedere che l'azione richiesta è new, cioè, la creazione di una nuova sessione di Devise. Cambiare il mio codice precedente è condizionale a:

if devise_controller? && resource_name == :user && action_name == 'new'

Funziona magnificamente.

Spero che questo aiuti qualcuno là fuori.


questo non applicherebbe il layout per entrambe le registrazioni # nuove e le sessioni # nuove?
Ayrad

13

La soluzione di gran lunga più semplice è creare semplicemente un layout chiamato devise.html.haml nella cartella app / views / layouts. e la magia di Rails si occupa del resto.

app/views/layouts/devise.html.haml

3
questo è il modo più semplice per impostare un layout per devise. Grazie!
catarro

8

Ecco come l'ho fatto. Volevo un layout diverso se l'utente doveva accedere, ma un layout diverso se l'utente doveva modificare il proprio profilo.

Sto usando Rails 4.1.1

Nel controller dell'applicazione, aggiungi questo:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  layout :layout_by_resource

  # Define the permitted parameters for Devise.
  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :lastname, :email, :password, :password_confirmation)}
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:avatar, :firstname, :lastname, :email, :password, :password_confirmation, :current_password) }
  end

  def layout_by_resource
    if devise_controller? and user_signed_in?
      'dashboard'
    else
      'application'
    end
  end
end

7

Sorpreso di non vedere questa risposta da nessuna parte, ma puoi anche fare questo:

In route.rb, cambia la configurazione di devise in modo che assomigli a questo:

  devise_for :users, controllers: {
    sessions: 'sessions'
  }

Quindi in app / controllers / sessions_controller.rb

class SessionsController < Devise::SessionsController
  layout 'devise', only: [:new]
end

Ciò è particolarmente utile se è necessario eseguire sostituzioni logiche aggiuntive in uno qualsiasi dei controller Devise.


2
Questo è esattamente quello che stavo cercando! Nessuno degli altri ha funzionato per qualche motivo: /
djGrill

1

Solo nel caso in cui non lo sapessi, puoi anche utilizzare rake routesper vedere i percorsi nella tua app rails insieme all'azione / controller su cui sono mappati.

 new_user_registration GET    /accounts/sign_up(.:format)       {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET    /accounts/edit(.:format)          {:action=>"edit", :controller=>"devise/registrations"}
                       PUT    /accounts(.:format)               {:action=>"update", :controller=>"devise/registrations"}
                       DELETE /accounts(.:format)               {:action=>"destroy", :controller=>"devise/registrations"}

Sì ecco perché corrisponde alla nuova azione.
Jorge Israel Peña

0

Ecco una frase per coloro che desiderano che tutte le azioni di ideazione utilizzino un nuovo layout:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.