แทนที่ตัวควบคุมการลงทะเบียนประดิษฐ์


236

ฉันได้เพิ่มเขตข้อมูลลงในแบบฟอร์มการสมัครใช้งานซึ่งยึดตามแบบจำลองอื่นดูที่ฉันจะใช้แอตทริบิวต์แบบซ้อนกับแบบจำลองรุ่นสำหรับรายละเอียดเลือดได้อย่างไร ส่วนนี้ทำงานได้ดี

ปัญหาตอนนี้คือเมื่อฉันบันทึกมันล้มเหลวในการสร้างการกระทำของตัวควบคุมการลงทะเบียนที่จัดทำโดยประดิษฐ์ด้วยActiverecord::UnknownAttributeErrorในฟิลด์นี้ (บริษัท )

ฉันสมมติว่าฉันต้องการแทนที่คอนโทรลเลอร์การลงทะเบียนหรือมีวิธีที่ดีกว่า / ง่ายกว่าที่ฉันควรเข้าใกล้สิ่งนี้หรือไม่?


1
จริง ๆ แล้วฉันเขียนโพสต์บล็อกทั้งหมดในjacopretorius.net
Jaco Pretorius

คำตอบ:


354

ในแบบฟอร์มของคุณคุณจะส่งผ่านคุณลักษณะอื่น ๆ ผ่านการมอบหมายจำนวนมากที่ไม่ได้เป็นของรุ่นผู้ใช้ของคุณหรือรุ่นที่ซ้อนกัน?

ถ้าเป็นเช่นนั้นฉันเชื่อว่า ActiveRecord :: UnknownAttributeError ถูกกระตุ้นในกรณีนี้

มิฉะนั้นฉันคิดว่าคุณสามารถสร้างตัวควบคุมของคุณเองโดยสร้างสิ่งนี้:

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  def new
    super
  end

  def create
    # add custom create logic here
  end

  def update
    super
  end
end 

แล้วบอกให้ประดิษฐ์ใช้คอนโทรลเลอร์นั้นแทนค่าเริ่มต้นด้วย:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}

3
แต่คุณจะแน่ใจได้อย่างไรว่าผู้ออกแบบจะมองดู dir ในมุมมอง? ฉันลองทำเช่นนี้ แต่ประดิษฐ์วิธีเช่น "sign_in_and_redirect (resource_name, resource)" กำลังมองหามุมมองสำหรับเทมเพลต
AnApprentice

7
หากคุณต้องการกำหนดมุมมอง devise ของคุณเองคุณต้องสร้างมุมมองเหล่านั้นก่อนแล้ว devise จะตรวจสอบโฟลเดอร์มุมมองของคุณก่อนที่จะโหลดมุมมองจากอัญมณี ใน Rails 3 คือ: rails generate devise:viewsและใน Rails 2 (ฉันคิดว่า) เป็น:script/generate devise:views
theTRON

2
แฮ็คข้างต้นไม่สามารถทำงานได้กับ devise 1.0.8 ซึ่งเป็นเวอร์ชั่นที่ใช้กับ Rails 2
William Yeung

18
หากคุณแทนที่ตัวควบคุม Devise เช่นนี้ตรวจสอบให้แน่ใจว่าคุณได้คัดลอกมุมมองทั้งหมดจากแอพ / views / devise / การลงทะเบียนไปยังแอพ / views / registrations / (เปลี่ยนสำหรับตัวควบคุมใดที่คุณกำลังเอาชนะ)
Jamie Cobbett

31
หรือคุณสามารถออกจากมุมมองที่คุณประดิษฐ์ที่พวกเขาและเพิ่มในของคุณpaths.app.views << "app/views/devise" config/application.rb
theTRON

66

วิธีที่ดีและเป็นระเบียบมากขึ้นในการเอาชนะคอนโทรลเลอร์และมุมมอง Devise โดยใช้เนมสเปซ

สร้างโฟลเดอร์ต่อไปนี้:

app/controllers/my_devise
app/views/my_devise

ใส่คอนโทรลเลอร์ทั้งหมดที่คุณต้องการแทนที่ลงใน app / controllers / my_devise และเพิ่มMyDeviseเนมสเปซเข้ากับชื่อคลาสคอนโทรลเลอร์ Registrationsตัวอย่าง:

# app/controllers/my_devise/registrations_controller.rb
class MyDevise::RegistrationsController < Devise::RegistrationsController

  ...

  def create
    # add custom create logic here
  end

  ...    

end 

เปลี่ยนเส้นทางของคุณตาม:

devise_for :users,
           :controllers  => {
             :registrations => 'my_devise/registrations',
             # ...
           }

คัดลอกมุมมองที่จำเป็นทั้งหมดลงapp/views/my_deviseจากโฟลเดอร์ประดิษฐ์อัญมณีหรือการใช้rails generate devise:viewsลบมุมมองที่คุณไม่ได้เอาชนะและเปลี่ยนชื่อโฟลเดอร์devisemy_devise

วิธีนี้คุณจะมีการจัดระเบียบอย่างเรียบร้อยในสองโฟลเดอร์


1
สิ่งนี้คล้ายกับวิธีการที่ฉันใช้ แต่ฉันไม่รู้ว่าจะใช้ตรรกะที่กำหนดเองในcreateวิธีการของฉันเขียนทับของ Devise อย่างไร คอนโทรลเลอร์ที่สร้างขึ้นจากนั่งร้านของฉันที่ฉันแก้ไขทำงานได้ดี แต่คุณจะทำให้มันทำงานกับresourceธุรกิจของ Devise ได้อย่างไร
Kyle Carlson

@Vincent ขอบคุณ - ถ้าฉันต้องการแทนที่เพียงวิธีเดียวฉันจะเขียนเพียงวิธีที่ฉันต้องการแทนที่ - และทุกอย่างอื่นจะทำงานได้ตามปกติ? ความช่วยเหลือของคุณชื่นชมมาก
BKSpurgeon

MyDevise::RegistrationsController < Devise::RegistrationsControllerสร้างข้อผิดพลาดในการพึ่งพาแบบวงกลม ฉันกำลังทำอะไรผิดหรือเปล่า?
ianrandmckenzie

34

ฉันเชื่อว่ามีวิธีแก้ปัญหาที่ดีกว่าการเขียน RegistrationsController อีกครั้ง ฉันทำสิ่งเดียวกัน (ฉันเพิ่งมีองค์กรแทน บริษัท )

หากคุณตั้งค่ารูปแบบที่ซ้อนกันอย่างเหมาะสมทั้งในรุ่นและระดับการดูทุกอย่างทำงานได้อย่างมีเสน่ห์

รุ่นผู้ใช้ของฉัน:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable, :lockable and :timeoutable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  has_many :owned_organizations, :class_name => 'Organization', :foreign_key => :owner_id

  has_many :organization_memberships
  has_many :organizations, :through => :organization_memberships

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :username, :owned_organizations_attributes

  accepts_nested_attributes_for :owned_organizations
  ...
end

รูปแบบองค์กรของฉัน:

class Organization < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User'
  has_many :organization_memberships
  has_many :users, :through => :organization_memberships
  has_many :contracts

  attr_accessor :plan_name

  after_create :set_owner_membership, :set_contract
  ...
end

มุมมองของฉัน: 'ประดิษฐ์ / ลงทะเบียน / new.html.erb'

<h2>Sign up</h2>

<% resource.owned_organizations.build if resource.owned_organizations.empty? %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <p><%= f.label :name %><br />
    <%= f.text_field :name %></p>

  <p><%= f.label :email %><br />
    <%= f.text_field :email %></p>

  <p><%= f.label :username %><br />
    <%= f.text_field :username %></p>

  <p><%= f.label :password %><br />
    <%= f.password_field :password %></p>

  <p><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %></p>

  <%= f.fields_for :owned_organizations do |organization_form| %>

    <p><%= organization_form.label :name %><br />
      <%= organization_form.text_field :name %></p>

    <p><%= organization_form.label :subdomain %><br />
      <%= organization_form.text_field :subdomain %></p>

    <%= organization_form.hidden_field :plan_name, :value => params[:plan] %>

  <% end %>

  <p><%= f.submit "Sign up" %></p>
<% end %>

<%= render :partial => "devise/shared/links" %>

3
การย้ายลอจิก
บิวด์

ฉันสร้างตัวควบคุมประดิษฐ์และตอนนี้มีการดำเนินการสร้างตัวควบคุมที่เรียกใช้เมื่อผู้ใช้คลิกสมัครใช้งาน มีวิธี (เช่นการแทนที่ / รหัสตัวอย่างบางส่วน) ฉันสามารถใช้ Devise เพื่อเข้ารหัสรหัสผ่านและทำการตรวจสอบแบ็กเอนด์ของรหัสผ่านและฟิลด์อื่น ๆ ได้หรือไม่? และบันทึกลงในฐานข้อมูลโมเดลหรือไม่
HP

คุณสามารถเข้าถึงตัวแปรโลคัลresourceในมุมมองแทนตัวแปรอินสแตนซ์ของคลาสได้@resourceอย่างไร?
Chloe

12

คุณสามารถสร้างมุมมองและตัวควบคุมสำหรับกำหนดเองประดิษฐ์

ใช้

rails g devise:controllers users -c=registrations

และ

rails g devise:views 

มันจะคัดลอกตัวควบคุมและมุมมองเฉพาะจากอัญมณีไปยังแอปพลิเคชันของคุณ

ถัดไปบอกให้เราเตอร์ใช้คอนโทรลเลอร์นี้

devise_for :users, :controllers => {:registrations => "users/registrations"}

11

วิธีการที่ง่ายมากเพียงไปที่เทอร์มินัลแล้วพิมพ์ตาม

rails g devise:controllers users //This will create devise controllers in controllers/users folder

ถัดไปเพื่อใช้มุมมองที่กำหนดเอง

rails g devise:views users //This will create devise views in views/users folder

ตอนนี้อยู่ในไฟล์ route.rb ของคุณ

devise_for :users, controllers: {
           :sessions => "users/sessions",
           :registrations => "users/registrations" }

คุณสามารถเพิ่มคอนโทรลเลอร์อื่น ๆ ได้เช่นกัน สิ่งนี้จะทำให้การใช้ตัวควบคุมในโฟลเดอร์ผู้ใช้และมุมมองในโฟลเดอร์ผู้ใช้

ตอนนี้คุณสามารถปรับแต่งมุมมองตามที่คุณต้องการและเพิ่มตรรกะของคุณไปยังตัวควบคุมในโฟลเดอร์ตัวควบคุม / ผู้ใช้ สนุก !

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.