设计中sign_in动作的不同布局

Jor*_*eña 81 layout ruby-on-rails devise

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

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

Zee*_*han 95

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

根据如何:创建自定义布局 "您还可以使用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
Run Code Online (Sandbox Code Playgroud)

通常在登录后面的页面和不需要身份验证的页面之间进行布局区分,因此上述方法大部分时间都有效.但我也尝试使用action_name帮助器为特定动作设置布局,它就像魅力一样:

config.to_prepare do
    Devise::SessionsController.layout proc{ |controller| action_name == 'new' ? "devise"   : "application" }
end
Run Code Online (Sandbox Code Playgroud)

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

  • 另外,每次在config文件夹中的任何文件中进行更改时都不要忘记重新启动服务器,在本例中为Rails3的config/application.rb或Rails 2的config/environment.rb,以使更改生效. (3认同)

小智 63

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

  • 好方案!您还可以在/app/views/layouts/devise.html.erb中放置一个布局,并将其应用于_all_您的设计视图 (27认同)

Jor*_*eña 44

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

这是一个愚蠢的错误.事实是sign_in道路,而不是行动.查看相关的源代码,我可以看到所需的操作是new,即创建一个新的 Devise Session.将上述代码的条件更改为:

if devise_controller? && resource_name == :user && action_name == 'new'
Run Code Online (Sandbox Code Playgroud)

工作得很漂亮.

希望能帮到那里的人.


San*_*gha 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
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 8

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

app/views/layouts/devise.html.haml
Run Code Online (Sandbox Code Playgroud)

  • 这是为设计设置布局的最简单方法。谢谢! (3认同)

str*_*ics 7

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

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

  devise_for :users, controllers: {
    sessions: 'sessions'
  }
Run Code Online (Sandbox Code Playgroud)

然后在app/controllers/sessions_controller.rb中

class SessionsController < Devise::SessionsController
  layout 'devise', only: [:new]
end
Run Code Online (Sandbox Code Playgroud)

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

  • 这正是我想要的!其他人都没有因某些原因而工作:/ (2认同)