Переопределити контролер реєстрації


236

Я додав поле до форми реєстрації, заснованої на іншій моделі, див. Як я можу використовувати вкладені атрибути з моделлю придумки для деталей горі. Ця частина працює чудово.

Проблема полягає в тому, що коли я економлять, він не спрацьовує при створенні контролера реєстрації, який постачається розробником з Activerecord::UnknownAttributeErrorцього поля (компанії).

Я припускаю, що мені потрібно змінити контролер реєстрації, чи є кращий / простіший спосіб мені підійти до цього?


1
Я фактично написав цілу публікацію в блозі на цьому jacopretorius.net/2014/03/…
Яко Преторіус

Відповіді:


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
Але як ви переконаєтесь, що Devise виглядає в придумані для переглядів? Я намагаюся це зробити, але розробити такі способи, як "sign_in_and_redirect (ім'я ресурсу, ресурс)" шукають у вікнах шаблону.
Підручник

7
Якщо ви хочете налаштувати свої перегляди, просто спершу потрібно сформувати їх, і розробник перевірить папку переглядів перед завантаженням представлень із дорогоцінного каменю. У Rails 3 це: rails generate devise:viewsа в Rails 2 (я думаю) це:script/generate devise:views
ТРАН

2
вище хак не працює з розробкою 1.0.8, яка версія працює для рейок 2.
William Yeung

18
Якщо ви заміните такий контролер Devise, переконайтеся, що ви скопіювали всі перегляди з програми / представлення / розробку / реєстрації в додаток / перегляди / реєстрації / (змініть на той контролер, який ви перейдете).
Джеймі Коббетт

31
Крім того, ви можете залишити свої погляди, де вони є, і додати їх paths.app.views << "app/views/devise"до своїх config/application.rb.
ТРОН

66

Кращий та більш організований спосіб переосмислення контролерів та представлень за допомогою просторів імен:

Створіть такі папки:

app/controllers/my_devise
app/views/my_devise

Покладіть всі контролери, які ви хочете змінити, у додаток / контролери / 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, видаліть представлення, до яких ви не переосмислюєте, та перейменуйте deviseпапку my_devise.

Таким чином у вас буде все акуратно організовано у дві папки.


1
Це схоже на підхід, який я використовую, але я не знаю, яку власну логіку застосовувати в createметоді Devise, який я переписав. Мій модифікований контролер, який я змінив, працює чудово, але як ви змусите його працювати з resourceбізнесом Devise ?
Кайл Карлсон

@Вінсенте дякую - якщо я хочу переосмислити лише один метод, чи пишу я лише той метод, який я хочу переосмислити - і чи все інше буде працювати нормально? Ваша допомога дуже вдячна
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
Переміщення логіки побудови з точки зору на модель буде чистіше, см stackoverflow.com/questions/3544265#3764837
meleyal

Я створив контролери придумування, і тепер створюється дія контролера, що спрацьовує, коли користувач натискає кнопку Реєстрація. Чи є спосіб (наприклад, переосмислити / якийсь код прикладу), який я можу використовувати Devise для шифрування пароля та проведення перевірки пароля та інших полів? і зберегти його в базі даних моделей?
HP

Як ви можете отримати доступ до локальної змінної resourceу представленні замість змінної екземпляра класу @resource?
Хлоя

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

Ви також можете додати інші контролери. Це дозволить використовувати контролери в папці користувачів та перегляди в папці користувачів.

Тепер ви можете налаштувати свої погляди як бажання і додати свою логіку до контролерів у папці контролерів / користувачів. Насолоджуйтесь!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.