bố cục khác nhau cho hành động sign_in trong devise


84

Tôi đang cố gắng sử dụng một bố cục tùy chỉnh / khác có tên "devise" cho hành động sign_in. Tôi tìm thấy này trang trong wiki devise, và ví dụ thứ hai thậm chí còn nói rằng bạn có thể làm điều đó mỗi hành động (trong trường hợp này, sign_inhành động), nhưng nó cho thấy không có ví dụ về làm điều đó. Ai đó trên IRC đã nói với tôi rằng tôi có thể thử điều này:

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

Nhưng nó dường như không hoạt động vì nó vẫn đang tải bố cục ứng dụng mặc định. Tôi sẽ đánh giá cao sự giúp đỡ nào.

Câu trả lời:


96

Một cách khác để áp dụng bố cục tùy chỉnh cho một hành động như sau.

Theo Cách thực hiện: Tạo bố cục tùy chỉnh "Bạn cũng có thể đặt bố cục cho các bộ điều khiển Devise cụ thể bằng cách sử dụng lệnh gọi lại trong config / environment.rb (rails 2) hoặc config / application.rb (rails 3). Việc này cần được thực hiện trong gọi lại to_prepare vì nó được thực thi một lần trong quá trình sản xuất và trước mỗi yêu cầu trong quá trình phát triển. "

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

Thông thường, sự phân biệt bố cục được thực hiện giữa các trang đằng sau đăng nhập và các trang không yêu cầu xác thực, vì vậy cách tiếp cận trên hoạt động hầu hết thời gian. Nhưng tôi cũng đã thử nghiệm với việc sử dụng action_namehelper để thiết lập bố cục cho một hành động cụ thể và nó hoạt động như một sự quyến rũ:

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

Tôi nghĩ đây là cách tốt hơn và được xây dựng theo cách để thay đổi bố cục dựa trên devise controller / action thay vì tạo một helper trong ApplicationController.


3
Cũng đừng quên khởi động lại máy chủ mỗi khi bạn thực hiện thay đổi đối với bất kỳ tệp nào trong thư mục cấu hình, trong trường hợp này là config / application.rb cho Rails3 hoặc config / environment.rb cho Rails 2, để các thay đổi có ảnh hưởng.
Zeeshan

Hãy lưu ý, tôi đã thử phương pháp này trong rails 3.1 và nó làm cho việc tải nội dung từ thư mục nội dung chậm hơn đáng kể. Điều này sẽ không ảnh hưởng đến máy chủ sản xuất, nhưng khi bạn có nhiều hơn một vài tệp css / js, bạn sẽ nhận thấy điều đó.
Gazler

trong ví dụ trên, là nó có thể bố trí cấu hình cho các nguồn lực devise riêng biệt (ví dụ, chúng ta hãy giả vờ chúng ta có hai loại khác nhau của người dùng devise và từng nhu cầu bố trí riêng của họ)
ckarbass

Khi tôi thử điều này, tôi gặp lỗi rằng nó hiện đang cố lấy mẫu từ hai vị trí. Làm cách nào để bạn có được Rails để ghi đè các cài đặt trước đó của Devise?
Adam Grant

Đối với những người đã bỏ lỡ nó - thiết lập Rails 3 thì khác - thực hiện việc này trong: config / application.rb (rails 3).
Stone,

66

Tôi vừa tạo app / views / layouts / devise / session.html.erb và đặt bố cục của mình vào đó.


28
Giải pháp tuyệt vời! Bạn cũng có thể đặt một bố trí trong /app/views/layouts/devise.html.erb và có nó áp dụng cho tất cả các quan điểm devise của bạn
Basti

45

Tôi đã tìm ra, nhưng tôi sẽ giữ câu hỏi này ở đây phòng khi người khác tò mò.

Đó là một sai lầm ngu ngốc. Thực tế là sign_incon đường, không phải hành động. Nhìn vào nguồn liên quan , tôi có thể thấy rằng hành động bắt buộc là newtạo một Phiên phát triển mới . Thay đổi mã có điều kiện ở trên của tôi thành:

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

Hoạt động đẹp.

Hy vọng rằng sẽ giúp ai đó ngoài kia.


điều này sẽ không áp dụng bố cục cho cả đăng ký # mới và phiên # mới?
Ayrad

12

Giải pháp đơn giản nhất là chỉ tạo một bố cục có tên devise.html.haml trong thư mục app / views / layouts của bạn. và ma thuật Rails sẽ lo phần còn lại.

app/views/layouts/devise.html.haml

3
đó là cách đơn giản nhất để thiết lập bố cục cho thiết kế. Cám ơn!
phlegx

8

Đây là cách tôi đã làm điều đó. Tôi muốn một bố cục khác nếu người dùng phải đăng nhập, nhưng một bố cục khác nếu người dùng phải chỉnh sửa hồ sơ của mình.

Tôi đang sử dụng Rails 4.1.1

Trong bộ điều khiển ứng dụng, thêm cái này:

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

7

Ngạc nhiên khi không thấy câu trả lời này ở bất cứ đâu, nhưng bạn cũng có thể làm điều này:

Trong route.rb, hãy thay đổi cấu hình devise của bạn để trông giống như sau:

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

Sau đó, trong app / controllers / session_controller.rb

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

Điều này đặc biệt hữu ích nếu bạn cần thực hiện ghi đè logic bổ sung trong bất kỳ bộ điều khiển Devise nào.


2
Đây chính xác là những gì tôi đang tìm kiếm! Không ai trong số những người khác hoạt động vì một số lý do: /
djGrill

1

Chỉ trong trường hợp bạn không biết, bạn cũng có thể sử dụng rake routesđể xem các tuyến đường trong ứng dụng đường ray của mình cùng với hành động / bộ điều khiển mà chúng ánh xạ.

 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"}

Cảm ơn, tôi thực sự đã biết / thực sự biết về các tuyến đường rake, tôi đã không nghĩ trong một giây rằng 'sign_in' có thể không phải là tên của hành động thực tế, tôi đã tìm ra nó, sau đó tôi nhận ra rằng tất cả đều xoay quanh các phiên đó là lý do tại sao nó tương ứng với hành động mới.
Jorge Israel Peña

0

Đây là một phần mềm dành cho những ai muốn thực hiện tất cả các hành động để sử dụng bố cục mới:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.