J'ai ajouté un champ au formulaire d'inscription basé sur un modèle différent, voir Comment utiliser des attributs imbriqués avec le modèle complexe pour obtenir les détails sanglants. Cette partie fonctionne bien.
Le problème maintenant, c’est que lors de l’enregistrement, il échoue dans l’action de création du contrôleur d’enregistrements fournie par le contrôleur avec un Activerecord::UnknownAttributeError
sur ce champ (société).
Je suppose que je dois remplacer le contrôleur des inscriptions ou existe-t-il un moyen meilleur/plus simple d’approche?
Dans votre formulaire, transmettez-vous d'autres attributs, via une affectation en masse qui n'appartient pas à votre modèle utilisateur, ou à l'un des modèles imbriqués?
Si tel est le cas, je pense que ActiveRecord :: UnknownAttributeError est déclenché dans cette instance.
Sinon, je pense que vous pouvez simplement créer votre propre contrôleur, en générant quelque chose comme ceci:
# 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
Et dites ensuite à utiliser ce contrôleur à la place du contrôleur par défaut avec:
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Une manière plus efficace et mieux organisée de remplacer les contrôleurs et les vues Devise à l'aide d'espaces de noms:
Créez les dossiers suivants:
app/controllers/my_devise
app/views/my_devise
Placez tous les contrôleurs que vous souhaitez remplacer dans app/controllers/my_devise et ajoutez MyDevise
namespace aux noms de classe du contrôleur. Registrations
exemple:
# app/controllers/my_devise/registrations_controller.rb
class MyDevise::RegistrationsController < Devise::RegistrationsController
...
def create
# add custom create logic here
end
...
end
Changez vos itinéraires en conséquence:
devise_for :users,
:controllers => {
:registrations => 'my_devise/registrations',
# ...
}
Copiez toutes les vues requises dans app/views/my_devise
depuis le dossier Devise gem ou utilisez Rails generate devise:views
, supprimez les vues que vous ne substituez pas et renommez le dossier devise
en my_devise
.
De cette façon, vous aurez tout organisé dans deux dossiers.
Je pense qu'il existe une meilleure solution que de réécrire le RegistrationsController. J'ai fait exactement la même chose (j'ai juste Organisation au lieu de Compagnie).
Si vous définissez correctement votre formulaire imbriqué, au niveau du modèle et de la vue, tout fonctionne comme un charme.
Mon modèle d'utilisateur:
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
Mon modèle d'organisation:
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
Mon point de vue: "inventer/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" %>
Vous pouvez générer des vues et des contrôleurs pour la personnalisation de l'appareil.
Utilisation
Rails g devise:controllers users -c=registrations
et
Rails g devise:views
Il copiera des contrôleurs particuliers et des vues de gem vers votre application.
Ensuite, dites au routeur d’utiliser ce contrôleur:
devise_for :users, :controllers => {:registrations => "users/registrations"}
Méthodes très simples Il suffit d'aller au terminal et au type suivant
Rails g devise:controllers users //This will create devise controllers in controllers/users folder
Suivant pour utiliser des vues personnalisées
Rails g devise:views users //This will create devise views in views/users folder
maintenant dans votre fichier route.rb
devise_for :users, controllers: {
:sessions => "users/sessions",
:registrations => "users/registrations" }
Vous pouvez aussi ajouter d'autres contrôleurs. Cela facilitera l’utilisation des contrôleurs dans le dossier des utilisateurs et des vues dans le dossier des utilisateurs.
Vous pouvez maintenant personnaliser les vues à votre guise et ajouter votre logique aux contrôleurs du dossier contrôleurs/utilisateurs. Prendre plaisir !
crée les inscriptions du contrôleur et remplace sa classe héritée par la classe prédéfinie Devise :: RegistrationsController
# 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
après cela, définissez les itinéraires vers:
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}