Mengganti merancang pengontrol pendaftaran

236

Saya telah menambahkan bidang ke formulir pendaftaran yang didasarkan pada model yang berbeda, lihat Bagaimana cara menggunakan atribut bersarang dengan model menyusun untuk detail berdarah. Bagian ini berfungsi dengan baik.

Masalahnya sekarang adalah ketika saya menyimpan, itu gagal dalam tindakan membuat pengendali pendaftaran yang disediakan oleh merancang dengan Activerecord::UnknownAttributeError bidang ini (perusahaan).

Saya berasumsi saya perlu mengganti controller registrasi, atau apakah ada cara yang lebih baik / lebih mudah saya harus mendekati ini?

Craig McGuff
sumber
1
Saya sebenarnya menulis seluruh posting blog di jacopretorius.net/2014/03/…
Jaco Pretorius

Jawaban:

354

Dalam formulir Anda, apakah Anda meneruskan atribut lain, melalui penugasan massal yang bukan milik model pengguna Anda, atau salah satu model bersarang?

Jika demikian, saya percaya ActiveRecord :: UnknownAttributeError dipicu dalam hal ini.

Kalau tidak, saya pikir Anda bisa membuat controller sendiri, dengan menghasilkan sesuatu seperti ini:

# 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 

Dan kemudian kirim alat untuk menggunakan kontroler itu daripada default dengan:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
theTRON
sumber
3
Tapi bagaimana Anda memastikan merancang tampak dalam dir merancang untuk pandangan? Saya mencoba ini tetapi menemukan metode seperti "sign_in_and_redirect (resource_name, resource)" mencari dalam tampilan untuk template.
AnApprentice
7
Jika Anda ingin menyesuaikan tampilan rancangan Anda, Anda hanya perlu membuatnya terlebih dahulu dan merancang akan memeriksa folder tampilan Anda sebelum memuat tampilan dari permata. Dalam Rails 3 itu: rails generate devise:viewsdan dalam Rails 2 (saya pikir) itu:script/generate devise:views
theTRON
2
retasan di atas tidak bekerja dengan merancang 1.0.8 yang merupakan versi berfungsi untuk rel 2.
William Yeung
18
Jika Anda mengganti pengontrol Rancangan seperti ini, pastikan Anda menyalin semua tampilan dari aplikasi / tampilan / rancang / registrasi ke aplikasi / tampilan / registrasi / (ubah untuk pengontrol mana pun yang Anda timpa).
Jamie Cobbett
31
Atau Anda dapat meninggalkan tampilan alat Anda di mana mereka berada dan menambahkan paths.app.views << "app/views/devise"Anda config/application.rb.
theTRON
66

Cara yang lebih baik dan lebih terorganisir untuk menimpa Rancang pengontrol dan tampilan menggunakan ruang nama:

Buat folder berikut:

app/controllers/my_devise
app/views/my_devise

Masukkan semua pengontrol yang ingin Anda timpa ke app / controllers / my_devise dan tambahkan MyDevisenamespace ke nama kelas pengontrol. Registrationscontoh:

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

  ...

  def create
    # add custom create logic here
  end

  ...    

end 

Ubah rute Anda sesuai:

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

Salin semua tampilan yang diperlukan ke dalam app/views/my_devisefolder Devise gem atau gunakan rails generate devise:views, hapus tampilan yang tidak Anda timpa dan ubah nama devisefolder menjadi my_devise.

Dengan cara ini Anda akan mengatur segalanya dengan rapi dalam dua folder.

Vincent
sumber
1
Ini mirip dengan pendekatan yang saya ambil, tetapi saya tidak tahu logika kebiasaan apa yang harus dimasukkan dalam createmetode Devise's yang saya timpa. Pengontrol perancah yang saya buat yang saya modifikasi berfungsi dengan baik, tetapi bagaimana Anda membuatnya bekerja dengan resourcebisnis Devise ?
Kyle Carlson
@Incent terima kasih - jika saya ingin mengganti hanya satu metode, apakah saya menulis hanya metode yang ingin saya timpa - dan akankah semuanya berjalan seperti biasa? Bantuan Anda sangat dihargai
BKSpurgeon
MyDevise::RegistrationsController < Devise::RegistrationsControllermenciptakan kesalahan ketergantungan melingkar. Apakah saya melakukan sesuatu yang salah?
ianrandmckenzie
34

Saya percaya ada solusi yang lebih baik daripada menulis ulang RegistrationsController. Saya melakukan hal yang persis sama (saya hanya memiliki Organisasi alih-alih Perusahaan).

Jika Anda mengatur bentuk sarang dengan benar, pada tingkat model dan tampilan, semuanya berfungsi seperti pesona.

Model Pengguna Saya:

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

Model Organisasi Saya:

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

Pandangan saya: 'merancang / registrasi / 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" %>
thb
sumber
3
Memindahkan logika build dari tampilan ke model akan lebih bersih, lihat stackoverflow.com/questions/3544265#3764837
meleyal
Saya membuat pengontrol pengendali dan sekarang membuat aksi pengontrol dibuat terpicu ketika pengguna mengklik Daftar. Apakah ada cara (seperti mengganti / beberapa kode contoh) saya dapat menggunakan Rancangan untuk mengenkripsi kata sandi dan melakukan pemeriksaan backend kata sandi dan bidang lainnya? dan menyimpannya ke model database?
HP
Bagaimana Anda bisa mengakses variabel lokal resourcedalam tampilan alih-alih variabel instance kelas @resource?
Chloe
12

Anda dapat menghasilkan tampilan dan pengontrol untuk merancang kustomisasi.

Menggunakan

rails g devise:controllers users -c=registrations

dan

rails g devise:views 

Ini akan menyalin pengontrol dan tampilan tertentu dari permata ke aplikasi Anda.

Selanjutnya, beri tahu router untuk menggunakan pengontrol ini:

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

Metode yang sangat sederhana Cukup buka terminal dan ketik berikut

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

Selanjutnya untuk menggunakan tampilan khusus

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

sekarang di file route.rb Anda

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

Anda dapat menambahkan pengontrol lain juga. Ini akan membuat alat untuk menggunakan pengontrol di folder pengguna dan tampilan di folder pengguna.

Sekarang Anda dapat menyesuaikan tampilan sesuai keinginan dan menambahkan logika Anda ke pengontrol di folder pengontrol / pengguna. Nikmati !

Pradeep Sapkota
sumber