Используйте обе учетные записи и пользовательские таблицы с Devise - PullRequest
19 голосов
/ 29 ноября 2011

Я работаю с Rails 3.1.0 и Devise 1.4.8, и я новичок в обоих.

Я хочу разрешить нескольким пользователям иметь учетную запись.Первый зарегистрированный пользователь создает учетную запись (вероятно, для своей компании), затем этот пользователь может добавить больше пользователей.Пользователь всегда связан только с одной учетной записью.

У меня есть таблицы пользователей и учетных записей.Сокращенные модели:

class User < ActiveRecord::Base
  belongs_to :account
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable,
     :confirmable, :lockable, :timeoutable
  attr_accessible :email, :password, :password_confirmation, :remember_me
end

class Account < ActiveRecord::Base
  has_many :users, :dependent => :destroy
  attr_accessible :name, :account_type
end

Вопрос, когда первый пользователь регистрируется, как мне создать учетную запись и пользователя?

  • Нужно ли изменять/ переопределить Devise registrations_controller, что-то вроде ответа здесь ?Я не мог понять, как создать учетную запись, а затем передать ее в Devise для создания пользователя.

  • account_id уже в модели пользователя.Должен ли я добавить account_name и account_type в модель User и создать новую запись Account, если account_id не передан?В этом случае я пытаюсь скрыть создание учетной записи от Devise, но не уверен, что это сработает, поскольку мне все еще нужно запрашивать account_name и account_type на странице регистрации.

Ответы [ 3 ]

23 голосов
/ 16 декабря 2011

Наконец-то все заработало, используя вложенные атрибуты.Как обсуждалось в комментариях к ответу Кентона, этот пример перевернут.Если вы хотите, чтобы на одну учетную запись приходилось несколько пользователей, сначала необходимо создать учетную запись, а затем - пользователя, даже если для начала вы создадите только одного пользователя.Затем вы пишете свой собственный контроллер учетных записей и просматриваете его в обход представления Devise.Функциональность Devise для отправки электронных писем с подтверждением и т. Д. По-прежнему работает, если вы просто создаете пользователя напрямую, то есть эта функциональность должна быть частью автоматических функций в Devise model ;не требует использования контроллера Devise.

Выдержки из соответствующих файлов:

Модели в приложении / моделях

class Account < ActiveRecord::Base
  has_many :users, :inverse_of => :account, :dependent => :destroy
  accepts_nested_attributes_for :users
  attr_accessible :name, :users_attributes
end

class User < ActiveRecord::Base
  belongs_to :account, :inverse_of => :users
  validates :account, :presence => true
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable, :timeoutable
  attr_accessible :email, :password, :password_confirmation, :remember_me
end

spec / models / account_spec.rb Тест модели RSpec

it "should create account AND user through accepts_nested_attributes_for" do
  @AccountWithUser = { :name => "Test Account with User", 
                       :users_attributes => [ { :email => "user@example.com", 
                                                :password => "testpass", 
                                                :password_confirmation => "testpass" } ] }
  au = Account.create!(@AccountWithUser)
  au.id.should_not be_nil
  au.users[0].id.should_not be_nil
  au.users[0].account.should == au
  au.users[0].account_id.should == au.id
end

config / rout.rb

  resources :accounts, :only => [:index, :new, :create, :destroy]

controllers / accounts_controller.rb

class AccountsController < ApplicationController

  def new
    @account = Account.new
    @account.users.build # build a blank user or the child form won't display
  end

  def create
    @account = Account.new(params[:account])
    if @account.save
      flash[:success] = "Account created"
      redirect_to accounts_path
    else
      render 'new'
    end
  end

end

views / accounts / new.html.erb view

<h2>Create Account</h2>

<%= form_for(@account) do |f| %>
  <%= render 'shared/error_messages', :object => f.object %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>

  <%= f.fields_for :users do |user_form| %>
    <div class="field"><%= user_form.label :email %><br />
    <%= user_form.email_field :email %></div>
    <div class="field"><%= user_form.label :password %><br />
    <%= user_form.password_field :password %></div>
    <div class="field"><%= user_form.label :password_confirmation %><br />
    <%= user_form.password_field :password_confirmation %></div>
  <% end %>

  <div class="actions">
    <%= f.submit "Create account" %>
  </div>
<% end %>

Rails довольно требователен во множественном и единственном числе.Поскольку мы говорим: Account has_many Users:

  • он ожидает, что users_attributes (не user_attributes) в модели, и тестирует
  • , он ожидает массив из хешей для теста,даже если в массиве только один элемент, следовательно, [] вокруг {пользовательских атрибутов}.
  • ожидает, что @ account.users.build в контроллере.Мне не удалось заставить синтаксис f.object.build_users работать непосредственно в представлении.
1 голос
/ 29 ноября 2011

Не могли бы вы использовать что-то вроде того, что описано в этих RailsCasts?:

http://railscasts.com/episodes/196-nested-model-form-part-1

http://railscasts.com/episodes/197-nested-model-form-part-2

Вы можете настроить свои модели, как описано в этих скринкастах, используя accepts_nested_attributes_for.

Тогда ваша форма views / devise / registrations / new.html.erb будет иметь вид: user like normal и может включать вложенную форму для: account.

Так что-то вроде этого в этой форме по умолчанию:

<%= f.fields_for :account do |account_form| %>
<div>
  <p>
    <%= account_form.label :name, "Account Name", :class => "label" %>
    <%= account_form.text_field :name, :class => "text_field" %>
    <span class="description">(e.g., enter your account name here)</span>
  </p>
</div>

<div>
  <p>
    <%= account_form.label :company, "Company Name", :class => "label" %>
    <%= account_form.text_field :company, :class => "text_field" %>
  </p>
</div>
<% end %>

Это пример кода из приложения, над которым я работаю, и я использую гем simple_form, поэтому помощники, используемые в вашем приложении, могут отличаться, но вы, вероятно, поймете идею.

Таким образом, когда пользователь создается (когда он регистрируется), он также может заполнить информацию, которая будет использоваться моделью учетной записи для создания своей учетной записи после нажатия кнопки «Зарегистрироваться».

И вы можете захотеть установить атрибут для этого пользователя, например, «admin» ... звучит так, будто этот начальный пользователь будет пользователем «admin» для компании, хотя другие пользователи также могут иметь доступ.

Надеюсь, это поможет.

0 голосов
/ 22 января 2017

Лучшим решением было бы использовать драгоценный камень.

Простой способ: Милия драгоценного камня

Способ субдомена: Жемчужина квартиры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...