เค้าโครงที่แตกต่างกันสำหรับการดำเนินการ sign_in ในประดิษฐ์


84

ฉันกำลังพยายามใช้เค้าโครงอื่น / กำหนดเองชื่อ "ประดิษฐ์" สำหรับการดำเนินการ sign_in ฉันพบหน้านี้ในวิกิประดิษฐ์และตัวอย่างที่สองบอกว่าคุณสามารถทำได้ต่อการกระทำ (ในกรณีนี้คือ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

แต่ดูเหมือนจะไม่ทำงานเนื่องจากยังคงโหลดเค้าโครงแอปพลิเคชันเริ่มต้น ฉันอยากจะขอบคุณความช่วยเหลือใด ๆ.

คำตอบ:


96

อีกวิธีหนึ่งในการใช้โครงร่างแบบกำหนดเองสำหรับการดำเนินการมีดังต่อไปนี้

ตามวิธีการ: สร้างเลย์เอาต์แบบกำหนดเอง "นอกจากนี้คุณยังสามารถตั้งค่าโครงร่างสำหรับคอนโทรลเลอร์ Devise เฉพาะโดยใช้การเรียกกลับใน config / environment.rb (ราง 2) หรือ config / application.rb (ราง 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

โดยปกติแล้วความแตกต่างของเค้าโครงจะเกิดขึ้นระหว่างหน้าหลังการเข้าสู่ระบบและหน้าที่ไม่จำเป็นต้องมีการตรวจสอบสิทธิ์ดังนั้นวิธีการข้างต้นจึงใช้ได้ผลเกือบตลอดเวลา แต่ฉันยังได้ทดลองใช้ตัวaction_nameช่วยในการกำหนดเลย์เอาต์สำหรับแอ็คชั่นเฉพาะและมันก็ได้ผลเหมือนมีเสน่ห์:

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

ฉันคิดว่านี่เป็นวิธีที่ดีกว่าและสร้างขึ้นเพื่อเปลี่ยนเค้าโครงตามตัวควบคุม / การกระทำที่ประดิษฐ์ขึ้นแทนที่จะสร้างตัวช่วยใน ApplicationController


3
อย่าลืมรีสตาร์ทเซิร์ฟเวอร์ทุกครั้งที่คุณทำการเปลี่ยนแปลงในไฟล์ใด ๆ ในโฟลเดอร์ config ในกรณีนี้คือ config / application.rb สำหรับ Rails3 หรือ config / environment.rb สำหรับ Rails 2 เพื่อให้การเปลี่ยนแปลงมีผล
Zeeshan

ระวังฉันลองใช้วิธีนี้ในราง 3.1 และทำให้การโหลดเนื้อหาจากโฟลเดอร์ assets ช้าลงอย่างมาก สิ่งนี้จะไม่ส่งผลกระทบต่อเซิร์ฟเวอร์ที่ใช้งานจริง แต่เมื่อคุณมีไฟล์ css / js มากกว่าสองสามไฟล์คุณจะสังเกตเห็นได้
Gazler

ในตัวอย่างข้างต้นเป็นไปได้หรือไม่ที่จะกำหนดค่าเลย์เอาต์สำหรับทรัพยากรอุปกรณ์ที่แยกจากกัน (เช่นสมมติว่าเรามีผู้ใช้อุปกรณ์ที่แตกต่างกันสองประเภทและแต่ละคนต้องการเลย์เอาต์ของตนเอง)
ckarbass

เมื่อฉันลองสิ่งนี้ฉันได้รับข้อผิดพลาดว่าตอนนี้กำลังพยายามรับเทมเพลตจากสองตำแหน่ง คุณจะทำให้ Rails ลบล้างการตั้งค่าก่อนหน้าของ Devise ได้อย่างไร
Adam Grant

สำหรับผู้ที่พลาด - การตั้งค่า Rails 3 แตกต่างกัน - ทำสิ่งนี้ใน config / application.rb (ราง 3)
Stone

66

ฉันเพิ่งสร้าง app / views / layouts / devise / sessions.html.erb และวางเค้าโครงของฉันไว้ที่นั่น


28
ทางออกที่ดี! คุณยังสามารถวางเค้าโครงใน /app/views/layouts/devise.html.erb และนำไปใช้กับมุมมองที่คุณคิดได้ทั้งหมด
Basti

45

ฉันคิดออกแล้ว แต่ฉันจะเก็บคำถามนี้ไว้ที่นี่เผื่อว่าคนอื่นจะสงสัย

มันเป็นความผิดพลาดที่โง่เขลา ข้อเท็จจริงคือsign_inเส้นทางไม่ใช่การกระทำ มองไปที่แหล่งที่มาเกี่ยวข้องผมจะเห็นว่าจำเป็นต้องดำเนินการคือnewคือการสร้างใหม่ประดิษฐ์เซสชัน การเปลี่ยนเงื่อนไขของรหัสข้างต้นของฉันเป็น:

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

ทำงานได้อย่างสวยงาม

หวังว่าจะช่วยใครบางคนที่นั่น


สิ่งนี้จะไม่ใช้เค้าโครงสำหรับการลงทะเบียนทั้ง # ใหม่และเซสชัน # ใหม่หรือ
Ayrad

13

วิธีแก้ปัญหาที่ง่ายที่สุดคือสร้างเค้าโครงที่เรียกว่า devise.html.haml ในโฟลเดอร์ app / views / layouts และเวทมนตร์ของ Rails จะดูแลส่วนที่เหลือ

app/views/layouts/devise.html.haml

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

7

แปลกใจที่ไม่เห็นคำตอบนี้ทุกที่ แต่คุณสามารถทำได้:

ใน route.rb เปลี่ยนการกำหนดค่าอุปกรณ์ของคุณให้มีลักษณะดังนี้:

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

จากนั้นใน app / controllers / sessions_controller.rb

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

สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณต้องการทำการลบล้างตรรกะเพิ่มเติมในคอนโทรลเลอร์ Devise ใด ๆ


2
นี่คือสิ่งที่ฉันกำลังมองหา! ไม่มีคนอื่นทำงานด้วยเหตุผลบางประการ: /
djGrill

1

ในกรณีที่คุณไม่ทราบคุณยังสามารถใช้rake routesเพื่อดูเส้นทางในแอพทางรถไฟของคุณพร้อมกับแอ็คชั่น / คอนโทรลเลอร์ที่พวกเขาจับคู่ได้

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

ขอบคุณจริงๆฉันรู้ / รู้เกี่ยวกับเส้นทางคราดฉันไม่เคยคิดมาก่อนเลยว่า 'sign_in' อาจไม่ใช่ชื่อของการกระทำจริงฉันคิดว่ามันน่าจะเป็นแล้วฉันก็รู้ว่าทุกอย่างหมุนรอบเซสชัน ซึ่งเป็นสาเหตุที่สอดคล้องกับการกระทำใหม่
Jorge Israel Peña

0

นี่คือหนึ่งซับสำหรับผู้ที่ต้องการให้การกระทำทั้งหมดใช้รูปแบบใหม่:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' }
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.