Utilizza entrambe le tabelle Account e Utente con Devise

Sto lavorando con Rails 3.1.0 e Devise 1.4.8, e sono nuovo ad entrambi.

Voglio consentire più utenti per un account. Il primo utente a registrarsi crea l’account (probabilmente per la propria azienda), quindi quell’utente può aggiungere più utenti. Un utente è sempre collegato a esattamente un account.

Ho tabelle utenti e account. Modelli abbreviati:

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  :destroy attr_accessible :name, :account_type end 

La domanda è, quando il primo utente si iscrive, come posso creare sia l’account che l’utente?

Finalmente ha funzionato usando attributi nidificati. Come discusso nei commenti sulla risposta di Kenton, quell’esempio è invertito. Se vuoi più utenti per account, devi prima creare l’account, poi l’utente, anche se crei solo un utente con cui iniziare. Quindi scrivi il tuo controller e visualizza il tuo account, ignorando la vista Devise. La funzionalità di Devise per l’invio di e-mail di conferma, ecc sembra funzionare se si crea un utente direttamente, cioè che la funzionalità deve essere parte di cose automagiche nel modello Devise; non richiede l’uso del controller Devise.

Estratti dai file pertinenti:

Modelli in app / modelli

 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 Test modello RSpec

 it "should create account AND user through accepts_nested_attributes_for" do @AccountWithUser = { :name => "Test Account with User", :users_attributes => [ { :email => "[email protected]", :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 / routes.rb

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

controllori / 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 

vista visualizzazioni / account / new.html.erb

 

Create Account

<%= form_for(@account) do |f| %> <%= render 'shared/error_messages', :object => f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :users do |user_form| %>
<%= user_form.label :email %>
<%= user_form.email_field :email %>
<%= user_form.label :password %>
<%= user_form.password_field :password %>
<%= user_form.label :password_confirmation %>
<%= user_form.password_field :password_confirmation %>
<% end %>
<%= f.submit "Create account" %>
<% end %>

Rails è piuttosto schizzinoso sul plurale rispetto al singolare. Poiché diciamo che Account ha_molti utenti:

  • si aspetta che user_attributes (non user_attributes) nel modello e test
  • si aspetta una serie di hash per il test, anche se c'è un solo elemento nell'array, quindi [] attorno agli {user attributes}.
  • si aspetta @ account.users.build nel controller. Non ero in grado di ottenere la syntax f.object.build_users per lavorare direttamente nella vista.

Non potresti usare qualcosa di simile in questi Railscast ?:

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

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

Puoi configurare i tuoi modelli come descritto in quegli screencast, usando accept_nested_attributes_for.

Quindi, il tuo modulo views / devise / registration / new.html.erb potrebbe essere: user like normal, e potrebbe includere un form annidato per: account.

Quindi qualcosa di simile all’interno di quella forma predefinita:

 <%= f.fields_for :account do |account_form| %> 

<%= account_form.label :name, "Account Name", :class => "label" %> <%= account_form.text_field :name, :class => "text_field" %> (eg, enter your account name here)

<%= account_form.label :company, "Company Name", :class => "label" %> <%= account_form.text_field :company, :class => "text_field" %>

<% end %>

Questo è un codice di esempio da un’app a cui sto lavorando e sto utilizzando la gem simple_form, quindi gli helper utilizzati nella tua app potrebbero essere diversi, ma probabilmente ne avrai l’idea.

Quindi, quando un utente viene creato (quando si registra), può anche inserire le informazioni che verranno utilizzate dal modello Account per creare il proprio account una volta raggiunto il pulsante “Registrati”.

E potresti voler impostare un attributo su quell’utente come “admin” anche … sembra che questo utente iniziale sarà l’utente “admin” per la società, anche se altri utenti potrebbero avere accesso.

Spero possa aiutare.

La soluzione migliore sarebbe utilizzare una gem.

Modo semplice: gem Milia

Modo sottodominio: appartamento gem