другой макет для входа в систему в devise - PullRequest
80 голосов
/ 13 февраля 2011

Я пытаюсь использовать другой / пользовательский макет с именем "devise" для действия sign_in. Я нашел эту страницу в вики разработки, а во втором примере даже сказано, что вы можете выполнять ее за действие (в данном случае sign_in действие), но на этом примере не показано. Кто-то в IRC сказал мне, что я могу попробовать это:

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

Но, похоже, он не работает, так как все еще загружает макет приложения по умолчанию. Буду признателен за любую помощь.

Ответы [ 8 ]

92 голосов
/ 21 августа 2011

Другой способ применить пользовательский макет для действия заключается в следующем.

Согласно Как: создать пользовательские макеты"Вы также можете установить макет для определенных контроллеров Devise, используя обратный вызов в config / environment.rb (rails 2) или config / application.rb (rails 3) Это должно быть сделано в обратном вызове to_prepare, потому что он выполняется один раз в производстве и перед каждым запросом в разработке. "

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

Обычно разметка макета проводится между страницами за входом в систему и страницами, которые не требуют аутентификации, поэтому вышеуказанный подход работает большую часть времени. Но я также экспериментировал с использованием action_name помощника, чтобы установить макет для определенного действия, и он работал как шарм:

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

Я думаю, что это лучший и встроенный способ изменения макета на основе разработки контроллера / действия вместо создания помощника в ApplicationController.

61 голосов
/ 17 июня 2012

Я только что создал app / views / layouts / devise / sessions.html.erb и поместил туда свой макет.

44 голосов
/ 13 февраля 2011

Я понял это, но я оставлю этот вопрос здесь на случай, если другим людям будет любопытно.

Это была глупая ошибка.Дело в том, что sign_in это путь, не действие.Глядя на соответствующий источник , я вижу, что требуемое действие - new, т. Е. Создание нового сеанса разработки.Изменение условного кода выше:

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

Работает прекрасно.

Надеюсь, что это поможет кому-то там.

8 голосов
/ 02 июня 2015

Самое простое решение - просто создать макет devise.html.haml в папке app / views / layouts. а магия Рельсов позаботится обо всем остальном.

app/views/layouts/devise.html.haml
8 голосов
/ 12 мая 2014

Вот как я это сделал.Я хотел другой макет, если пользователь должен был войти в систему, но другой макет, если пользователь должен был отредактировать свой профиль.

Я использую Rails 4.1.1

В контроллере приложения добавьте следующее:

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 голосов
/ 16 декабря 2014

Удивлен, что нигде не вижу этот ответ, но вы также можете сделать это:

В файле route.rb измените конфигурацию вашего устройства, чтобы она выглядела примерно так:app / controllers / session_controller.rb

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

Это особенно полезно, если вам необходимо выполнить дополнительные логические переопределения в любом из контроллеров Devise.

1 голос
/ 13 февраля 2011

Просто если вы не знали, вы также можете использовать rake routes, чтобы увидеть маршруты в вашем приложении rails вместе с действием / контроллером, на который они отображаются.

 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"}
0 голосов
/ 12 августа 2012

Вот одна строка для тех, кто хочет, чтобы все разработанные действия использовали новый макет:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
...