Переопределить устройство регистрации регистраций

236

Я добавил поле в форму регистрации, основанное на другой модели, см. Как использовать вложенные атрибуты с моделью устройства для подробной информации. Эта часть работает нормально.

Проблема сейчас в том, что при сохранении происходит сбой в действии create контроллера регистраций, который предоставляется devise с Activerecord::UnknownAttributeErrorполем on (компания).

Я предполагаю, что мне нужно переопределить контроллер регистраций, или есть лучший / более простой способ, которым я должен подходить к этому?

Крейг МакГафф
источник
1
Я на самом деле написал целый пост в блоге на этом jacopretorius.net/2014/03/…
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 

А затем скажите devise для использования этого контроллера вместо стандартного с помощью:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
theTRON
источник
3
Но как вы можете убедиться, что devis выглядит в devir dir для представлений? Я пытаюсь это сделать, но разработаю такие методы, как "sign_in_and_redirect (resource_name, resource)", которые ищут во взглядах на шаблон.
Ученик
7
Если вы хотите настроить свои представления devise, вам просто нужно сначала сгенерировать их, а devise проверит папку ваших представлений перед загрузкой представлений из драгоценного камня. В Rails 3 это: rails generate devise:viewsа в Rails 2 (я думаю) это:script/generate devise:views
theTRON
2
вышеупомянутый хак не работает с devise 1.0.8, которая является версией для rails 2.
Уильям Йенг
18
Если вы переопределяете контроллер Devise, как это, убедитесь, что вы скопировали все представления из app / views / devise / registrations в app / views / registrations / (измените на любой контроллер, который вы переопределяете).
Джейми Коббетт
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папку Devise или используйте их rails generate devise:views, удалите виды, которые вы не переопределяете, и переименуйте deviseпапку my_devise.

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

Винсент
источник
1
Это похоже на подход, который я использую, но я не знаю, какую пользовательскую логику использовать в createметоде Devise'а я переписал. Мой созданный скаффолдом контроллер, который я модифицировал, прекрасно работает, но как сделать так, чтобы он работал с resourceбизнесом Devise ?
Кайл Карлсон
@ 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

Мой взгляд: 'devise / registrations / 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
источник
3
Перемещение логики построения с точки зрения на модель будет чище, см stackoverflow.com/questions/3544265#3764837
meleyal
Я сгенерировал контроллеры devise и теперь запускаю действие контроллера, когда пользователь нажимает кнопку Зарегистрироваться. Есть ли способ (например, переопределение / некоторый пример кода), чтобы я мог использовать Devise для шифрования пароля и выполнения внутренних проверок пароля и других полей? и сохранить его в базе данных модели?
HP
Как вы можете получить доступ к локальной переменной resourceв представлении вместо переменной экземпляра класса @resource?
Хлоя
12

Вы можете создавать представления и контроллеры для разработки настроек.

использование

rails g devise:controllers users -c=registrations

и

rails g devise:views 

Он скопирует определенные контроллеры и представления из gem в ваше приложение.

Далее скажите маршрутизатору использовать этот контроллер:

devise_for :users, :controllers => {:registrations => "users/registrations"}
user1201917
источник
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" }

Вы также можете добавить другие контроллеры. Это позволит использовать контроллеры в папке пользователей и представления в папке пользователей.

Теперь вы можете настроить свои представления по своему желанию и добавить свою логику для контроллеров в папке controllers / users. Наслаждайтесь !

Прадип Сапкота
источник