другой макет для действия sign_in в разработке

84

Я пытаюсь использовать другой / настраиваемый макет с именем "devise" для действия sign_in. Я нашел эту страницу в devise wiki, и во втором примере даже говорится, что вы можете делать это для каждого действия (в данном случае, 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

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

Хорхе Исраэль Пенья
источник

Ответы:

96

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

В соответствии с инструкциями по созданию пользовательских макетов "Вы также можете установить макет для конкретных контроллеров 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.

Zeeshan
источник
3
Также не забывайте перезапускать сервер каждый раз, когда вы вносите изменения в любой файл в папке config, в данном случае config / application.rb для Rails3 или config / environment.rb для Rails 2, чтобы изменения вступили в силу.
Zeeshan
Остерегайтесь, я пробовал этот метод в rails 3.1, и он значительно замедляет загрузку ресурсов из папки ресурсов. Это не повлияет на рабочие серверы, но когда у вас будет больше нескольких файлов css / js, вы это заметите.
Gazler
в приведенном выше примере можно ли настроить макеты для отдельных ресурсов разработки (например, представим, что у нас есть два разных типа пользователей устройства, и каждому из них нужен свой макет)
ckarbass
Когда я пытаюсь это сделать, я получаю сообщение об ошибке, что теперь он пытается получить шаблон из двух мест. Как заставить Rails переопределить предыдущие настройки Devise?
Адам Грант
Для тех, кто пропустил - установка Rails 3 другая - сделайте это в: config / application.rb (rails 3).
Stone
66

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

Джош
источник
28
Отличное решение! Вы также можете поместить макет в /app/views/layouts/devise.html.erb и применить его ко всем вашим представлениям разработки
Басти
45

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

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

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

Красиво работает.

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

Хорхе Исраэль Пенья
источник
не будет ли это применяться к макету как для регистраций # new, так и для сессий # new?
Ayrad
13

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

app/views/layouts/devise.html.haml
Джон
источник
3
это самый простой способ создать макет для разработки. Спасибо!
phlegx 04
8

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

Я использую 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

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

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

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

Затем в app / controllers / sessions_controller.rb

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

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

стритлогика
источник
2
Это именно то, что я искал! Никто из остальных по какой-то причине не работал: /
djGrill
1

На всякий случай, если вы не знали, вы также можете использовать его 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"}
Dty
источник
Спасибо, я действительно знал / знаю о маршрутах рейка, я просто ни на секунду не подумал, что 'sign_in' может не быть названием фактического действия, я подумал, что это будет, затем я понял, что все это вращается вокруг сеансов поэтому он соответствует новому действию.
Хорхе Исраэль Пенья,
0

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

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
влад
источник