інший макет для дії sign_in у розробці


84

Я намагаюся використовувати інший / спеціальний макет з назвою "розробити" для дії 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

Але це, здається, не працює, оскільки все ще завантажує макет програми за замовчуванням. Буду вдячний за будь-яку допомогу.

Відповіді:


96

Інший спосіб застосувати спеціальний макет для дії полягає в наступному.

Відповідно до " Як створити власні макети " "Ви також можете встановити макет для певних контролерів Devise, використовуючи зворотний виклик у config / environment.rb (рейки 2) або config / application.rb (рейки 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.


3
Також не забувайте перезавантажувати сервер щоразу, коли ви вносите зміни до будь-якого файлу в папці config, у цьому випадку config / application.rb для Rails3 або config / environment.rb для Rails 2, щоб зміни набрали чинності.
Zeeshan

Остерігайтеся, я спробував цей метод у рейках 3.1, і це робить завантаження активів з папки активів значно повільнішим. Це не вплине на робочі сервери, але коли у вас є кілька файлів css / js, ви це помітите.
Газлер

у наведеному вище прикладі чи можна налаштувати макети для окремих ресурсів розробника (наприклад, давайте зробимо вигляд, що у нас є два різні типи користувачів пристроїв і кожному потрібен власний макет)
ckarbass

Коли я спробую це, я отримую повідомлення про те, що зараз він намагається отримати шаблон із двох місць. Як змусити Rails замінити попередні налаштування Devise?
Адам Грант

Для тих, хто пропустив - налаштування Rails 3 інше - зробіть це в: config / application.rb (rails 3).
Stone

66

Я щойно створив app / views / layout / devise / session.html.erb і помістив туди свій макет.


28
Чудове рішення! Ви також можете розмістити макет в /app/views/layouts/devise.html.erb і попросити, щоб він застосовувався до всіх ваших переглядів пристроїв
Басті,

45

Я розібрався, але це питання я буду залишати тут на випадок, якщо іншим цікаво.

Це була дурна помилка. Справа в тому, що sign_inце шлях, а не дія. Переглядаючи відповідне джерело , я бачу, що потрібна дія полягає new, тобто, створення нового сесію Devise. Зміна мого вищезазначеного коду умовно на:

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

Працює красиво.

Сподіваюся, це допоможе комусь там.


чи не застосовуватиме це макет як для реєстрацій # нових, так і для сеансів # нових?
Айрад,

12

На сьогоднішній день найпростішим рішенням є просто створити макет, який називається devise.html.haml, у папці app / views / layout. а про решту піклується Rails magic.

app/views/layouts/devise.html.haml

3
це дуже простий спосіб встановити макет для розробки. Дякую!
phlegx

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

Здивований, що ніде не бачу цієї відповіді, але ви також можете зробити це:

У route.rb змініть конфігурацію свого пристрою, щоб виглядати приблизно так:

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

Потім в app / controllers / session_controller.rb

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

Це особливо корисно, якщо вам потрібно виконати додаткові перевизначення логіки в будь-якому з контролерів Devise.


2
Це саме те, що я шукав! Жоден з інших з якихось причин не працював: /
djGrill

1

Просто якщо ви не знали, ви також можете використовувати rake routesдля перегляду маршрутів у вашому додатку рейок разом із дією / контролером, на який вони зіставляються.

 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"}

Дякую, я насправді знав / знаю про рейкові маршрути, я просто ні секунди не думав, що 'sign_in' може не називати фактичну дію, я думав, що це буде, тоді я зрозумів, що все це обертається навколо сеансів саме тому вона відповідає новій дії.
Хорхе Ізраїль Пенья

0

Ось однокласний вкладиш для тих, хто хоче, щоб усі розроблені дії використовували новий макет:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.