web-dev-qa-db-fra.com

Ignorer le contrôleur des enregistrements de carte

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?

230
Craig McGuff

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

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.

66
Vincent

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" %>
33
thb

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

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 !

10
Pradeep Sapkota

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"}
0
Jai Kumar Rajput