设计中sign_in动作的不同布局

时间:2011-02-13 02:34:24

标签: ruby-on-rails layout devise

我正在尝试为sign_in操作使用名为“devise”的不同/自定义布局。我在设计维基中找到了this页面,第二个例子甚至说你可以按行动(在这种情况下,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 个答案:

答案 0 :(得分:92)

为操作应用自定义布局的另一种方法如下。

根据How To: Create custom layouts“您还可以使用config / environment.rb(rails 2)或config / application.rb(rails 3)中的回调设置特定Devise控制器的布局。这需要完成在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中创建帮助器。

答案 1 :(得分:61)

我刚刚创建了app / views / layouts / devise / sessions.html.erb并将我的布局放在那里。

答案 2 :(得分:44)

我明白了,但我会在这里保留这个问题以防其他人好奇。

这是一个愚蠢的错误。事实是sign_in是路径,不是动作。查看relevant source,我可以看到所需的操作是new,即创建新的设计会话。将上述代码的条件更改为:

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

工作得很漂亮。

希望帮助那里的人。

答案 3 :(得分: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

答案 4 :(得分:8)

迄今为止最简单的解决方案是在app / views / layouts文件夹中创建一个名为devise.html.haml的布局。 Rails魔术照顾其余部分。

app/views/layouts/devise.html.haml

答案 5 :(得分:7)

很惊讶在任何地方都没有看到这个答案,但你也可以这样做:

在routes.rb中,将您的设备配置更改为如下所示:

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

然后在app / controllers / sessions_controller.rb

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

如果您需要在任何Devise控制器中执行其他逻辑覆盖,这将非常有用。

答案 6 :(得分: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"}

答案 7 :(得分:0)

对于那些希望所有设计操作都使用新布局的人来说,这是一个单行代码:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
相关问题