Ruby-on-rails 设计中 sign_in 操作的不同布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4982073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:24:29  来源:igfitidea点击:

different layout for sign_in action in devise

ruby-on-railslayoutdevise

提问by Jorge Israel Pe?a

I'm trying to use a different/custom layout named "devise" for the sign_in action. I found thispage in the devise wiki, and the second example even says you can do it per-action (in this case, sign_inaction), but it shows no example of doing that. Someone on IRC told me I could try this:

我正在尝试为 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

But it does not seem to be working as it's still loading the default application layout. I would appreciate any help.

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

采纳答案by Jorge Israel Pe?a

I figured it out, but I'll keep this question here in case other people are curious.

我想通了,但我会保留这个问题,以防其他人好奇。

It was a stupid mistake. The fact is sign_inis the path, notthe action. Looking at the relevant source, I can see that the required action is new, i.e., creating a newDevise Session. Changing my above code's conditional to:

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

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

Works beautifully.

工作精美。

Hope that helps someone out there.

希望能帮助那里的人。

回答by Zeeshan

Another way to apply custom layout for an action is as following.

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

According to How To: Create custom layouts"You can also set the layout for specific Devise controllers using a callback in config/environment.rb (rails 2) or config/application.rb (rails 3). This needs to be done in a to_prepare callback because it's executed once in production and before each request in development."

根据How To: Create custom layouts“您还可以使用 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

Usually a layout distinction is made between pages behind login and pages which do not require authentication, so the above approach works most of the time. But I also experimented with using action_namehelper to set a layout for a particular action and it worked like charm:

通常在登录后的页面和不需要身份验证的页面之间进行布局区分,因此上述方法在大多数情况下都有效。但我也尝试过使用action_namehelper 为特定操作设置布局,它的工作原理非常迷人:

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

I think this is the better and built in way to change the layout based on devise controller/action instead of creating a helper in ApplicationController.

我认为这是更好的内置方式来更改基于设计控制器/操作的布局,而不是在 ApplicationController 中创建帮助程序。

回答by Josh

I just created app/views/layouts/devise/sessions.html.erb and put my layout in there.

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

回答by John

The by far simplest solution is to just create a layout called devise.html.haml in your app/views/layouts folder. and the Rails magic takes care of the rest.

迄今为止最简单的解决方案是在您的 app/views/layouts 文件夹中创建一个名为 devise.html.haml 的布局。剩下的就交给 Rails 魔法了。

app/views/layouts/devise.html.haml

回答by Sankalp Singha

This is how I did it. I wanted a different layout if the user had to sign in, but a different layout if the user had to edit his/her profile.

我就是这样做的。如果用户必须登录,我想要一个不同的布局,但如果用户必须编辑他/她的个人资料,我想要一个不同的布局。

I am using Rails 4.1.1

我正在使用 Rails 4.1.1

In the application controller, add this :

在应用程序控制器中,添加以下内容:

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

回答by streetlogics

Surprised to not see this answer anywhere, but you can also do this:

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

In routes.rb, change your devise config to look something like this:

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

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

Then in app/controllers/sessions_controller.rb

然后在 app/controllers/sessions_controller.rb

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

This is especially useful if you need to do additional logic overrides in any of the Devise controllers.

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

回答by Dty

Just incase you didn't know, you can also use rake routesto see the routes in your rails app along with the action/controller they map to.

以防万一您不知道,您还可以使用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"}

回答by vlad

Here's a one-liner for those who want all devise actions to use a new layout:

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

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end