devise中sign_in动作的不同布局

我正在尝试为sign_in操作使用名为“devise”的不同/自定义布局。 我在devisewiki中find了这个页面,第二个例子甚至说你可以按照每个动作(在这种情况下,是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 

但它似乎没有工作,因为它仍然加载默认的应用程序布局。 我将不胜感激任何帮助。

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

根据如何:创build自定义布局 “您还可以在config / environment.rb(rails 2)或config / application.rb(rails 3)中使用callback来为特定的Devise控制器设置布局,这需要在to_preparecallback,因为它在生产中和开发中的每个请求之前执行一次。

 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 

通常情况下,在login页面和不需要authentication的页面之间进行布局区分,所以上面的方法大部分时间都是有效的。 但是我也尝试过使用action_name助手为特定的动作设置布局,它的工作方式就像是魅力:

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

我认为这是更好的和build立在基于devise控制器/行动,而不是在ApplicationController中创build一个帮手的方式来改变布局。

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

我明白了,但如果其他人好奇,我会把这个问题留在这里。

这是一个愚蠢的错误。 事实是sign_in是path, 而不是行动。 从相关的资料来源可以看出,所要求的行动是new ,即创造一个新的devise会议。 改变我的上面的代码的条件为:

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

精美的作品。

希望能帮助那里的人。

我就是这么做的 如果用户必须login,我想要一个不同的布局,但如果用户不得不编辑他/她的个人资料,则需要不同的布局。

我正在使用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 

最简单的解决scheme是在app / views / layouts文件夹中创build一个名为devise.html.haml的布局。 而Rails的魔法照顾其余的。

 app/views/layouts/devise.html.haml 

惊奇的是没有看到这个答案的任何地方,但你也可以这样做:

在routes.rb中,将你的deviseconfiguration改为如下所示:

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

然后在应用程序/控制器/ sessions_controller.rb

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

如果您需要在任何Devise控制器中执行额外的逻辑覆盖,这将特别有用。

只要你不知道,你也可以使用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"} 

对于那些希望所有devise操作使用新布局的人来说,

 class ApplicationController < ActionController::Base protect_from_forgery layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' } end