我正在尝试为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
但它似乎没有工作,因为它仍在加载默认的应用程序布局。我将不胜感激任何帮助。
答案 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