Ok, donc j'ai travaillé à travers et est venu à la solution suivante.
J'avais besoin de costumize concevoir un peu, mais ce n'est pas compliqué.
Le modèle de l'Utilisateur
# user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
belongs_to :rolable, :polymorphic => true
end
Le modèle Client
# customer.rb
class Customer < ActiveRecord::Base
has_one :user, :as => :rolable
end
Le Concepteur de modèle
# designer.rb
class Designer < ActiveRecord::Base
has_one :user, :as => :rolable
end
Donc, le modèle de l'Utilisateur est un simple polymorphe de l'association, de définir si c'est un Client ou d'un Designer.
La prochaine chose que je n'avais plus qu'à générer le dispositif de vues avec rails g devise:views
de faire partie de mon application. Depuis que j'ai seulement besoin de l'enregistrement à être personnalisés j'ai gardé l' app/views/devise/registrations
le dossier seul et retiré le reste.
Puis je l'ai adapté les enregistrements de la vue pour les nouvelles inscriptions, qui peut être trouvé dans app/views/devise/registrations/new.html.erb
après vous les a générés.
<h2>Sign up</h2>
<%
# customized code begin
params[:user][:user_type] ||= 'customer'
if ["customer", "designer"].include? params[:user][:user_type].downcase
child_class_name = params[:user][:user_type].downcase.camelize
user_type = params[:user][:user_type].downcase
else
child_class_name = "Customer"
user_type = "customer"
end
resource.rolable = child_class_name.constantize.new if resource.rolable.nil?
# customized code end
%>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= my_devise_error_messages! # customized code %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<% # customized code begin %>
<%= fields_for resource.rolable do |rf| %>
<% render :partial => "#{child_class_name.underscore}_fields", :locals => { :f => rf } %>
<% end %>
<%= hidden_field :user, :user_type, :value => user_type %>
<% # customized code end %>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>
Pour chaque type d'Utilisateur que j'ai créé une partiels séparés avec les champs personnalisés pour le type d'Utilisateur, c'est à dire le Concepteur --> _designer_fields.html
<div><%= f.label :label_name %><br />
<%= f.text_field :label_name %></div>
Puis-je configurer les routes pour concevoir l'utilisation de la coutume contrôleur sur les inscriptions
devise_for :users, :controllers => { :registrations => 'UserRegistrations' }
Ensuite, j'ai généré un contrôleur pour gérer vos processus d'inscription, copié le code source d'origine de l' create
méthode Devise::RegistrationsController
et l'a modifié à ma façon (n'oubliez pas déplacer les fichiers vers le dossier approprié dans mon cas app/views/user_registrations
class UserRegistrationsController < Devise::RegistrationsController
def create
build_resource
# customized code begin
# crate a new child instance depending on the given user type
child_class = params[:user][:user_type].camelize.constantize
resource.rolable = child_class.new(params[child_class.to_s.underscore.to_sym])
# first check if child instance is valid
# cause if so and the parent instance is valid as well
# it's all being saved at once
valid = resource.valid?
valid = resource.rolable.valid? && valid
# customized code end
if valid && resource.save # customized code
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => inactive_reason(resource) if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords(resource)
respond_with_navigational(resource) { render_with_scope :new }
end
end
end
Ce que tout fait est que le contrôleur détermine quel type d'utilisateur doit être créé en fonction de l' user_type
paramètre qui est livré à la manette create
méthode par le champ caché de la vue qui utilise le paramètre par un simple GET-paramètre dans l'URL.
Par exemple:
Si vous allez à l' /users/sign_up?user[user_type]=designer
vous pouvez créer un Designer.
Si vous allez à l' /users/sign_up?user[user_type]=customer
vous pouvez créer un Client.
L' my_devise_error_messages!
méthode est une méthode d'aide, qui gère également les erreurs de validation dans le modèle associatif, basé sur l'original de l' devise_error_messages!
méthode
module ApplicationHelper
def my_devise_error_messages!
return "" if resource.errors.empty? && resource.rolable.errors.empty?
messages = rolable_messages = ""
if !resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
end
if !resource.rolable.errors.empty?
rolable_messages = resource.rolable.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
end
messages = messages + rolable_messages
sentence = I18n.t("errors.messages.not_saved",
:count => resource.errors.count + resource.rolable.errors.count,
:resource => resource.class.model_name.human.downcase)
html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML
html.html_safe
end
end
Mise à JOUR:
Pour être en mesure de soutenir de tels axes /designer/sign_up
et /customer/sign_up
vous pouvez effectuer les opérations suivantes dans votre fichier de routes:
# routes.rb
match 'designer/sign_up' => 'user_registrations#new', :user => { :user_type => 'designer' }
match 'customer/sign_up' => 'user_registrations#new', :user => { :user_type => 'customer' }
Aucun paramètre n'est pas utilisé dans les routes de la syntaxe interne de passe pour les paramètres de hachage. Donc, :user
est passée à la params de hachage.
Alors... c'est elle. Avec un peu de tweeking ici et là j'ai eu de travail, dans un sens général, qui est facilement extensible avec de nombreux autres Utilisateurs des modèles de partage d'une commune de la table User.
J'espère que quelqu'un le trouve utile.
0 votes
Quelqu'un a-t-il des suggestions ?