ruby-on-rails – 在Rails中使用Devise的单表继承4

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 在Rails中使用Devise的单表继承4前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经阅读了 here,herehere的帖子,但是我仍然无法实现单表继承.

理想情况下,我想要有两个注册路径(一个用于客户端,一个用于提供程序),具有通用字段名称,电子邮件,密码和confirm_password,并且提供者注册具有一个额外的单选按钮字段来指定提供者类型.我正在通过设计进行注册.点击注册表单上的提交后,用户将被重定向到对于客户端和提供者完全不同的第二个表单(我一直在使用资源的编辑页面).

就像现在一样,如果我只是通过User进行操作,一切正常,但一旦添加了单表继承,注册表就告诉我他们缺少第二个表单的要求.

这是我的config / routes.rb

  1. Rails.application.routes.draw do
  2. devise_for :users,:controllers => {:sessions => "sessions"},:skip=> :registrations
  3. devise_for :clients,:providers,:skip=> :sessions
  4. resources :clients
  5. resources :providers
  6. root :to=>'pages#home'
  7. match '/home',to: 'pages#home',via: 'get'
  8. end

我的机型看起来如下:

用户

  1. class User < ActiveRecord::Base
  2.  
  3. before_save {self.email = email.downcase}
  4.  
  5. devise :database_authenticatable,:registerable,:recoverable,:rememberable,:trackable,:validatable
  6.  
  7. validates :name,presence: true,length: {maximum: 50}
  8. validates :email,:email => {:ban_disposable_email => true,:message => I18n.t('validations.errors.models.user.invalid_email')},uniqueness: { case_sensitive: false }
  9.  
  10. validates :password,length: {minimum: 6},:if=>:password_validation_required?
  11.  
  12. logo_TYPES = ['image/jpeg','image/png','image/gif']
  13. has_attached_file :avatar,:styles => {:medium => "300x300>",:square=>"200x200>",:thumb => "100x100>" },:default_url => '/assets/missing_:style.png'
  14. validates_attachment_content_type :avatar,:content_type => logo_TYPES
  15.  
  16. def password_validation_required?
  17. !@password.blank?
  18. end
  19. end

客户:

  1. class Client < User
  2. validates :industry,presence: true
  3. validates :city,presence: true
  4. validates :state,presence: true
  5. validates :description,length: {minimum: 50,maximum: 300}
  6. end

提供者:

  1. class Provider < User
  2. validates :ptype,presence: true
  3. validates :education,presence: true
  4. validates :biography,presence:true,maximum: 300}
  5. validates_format_of :linkedin,:with => URI::regexp(%w(http https))
  6. validates :resume,presence: true
  7. has_many :disciplines
  8. end

这里是我的控制器:

  1. class SessionsController < Devise::SessionsController
  2. def create
  3. rtn = super
  4. sign_in(resource.type.underscore,resource.type.constantize.send(:find,resource.id)) unless resource.type.nil?
  5. rtn
  6. end
  7. end
  8.  
  9. class RegistrationsController < Devise::RegistrationsController
  10. protected
  11. def after_sign_up_path_for(resource)
  12. if resource.is_a?(User)
  13. if current_user.is_a?(Client)
  14. edit_client_path(current_user.id)
  15. elsif current_user.is_a?(Provider)
  16. edit_provider_path(current_user.id)
  17. end
  18. else
  19. super
  20. end
  21. end
  22. end
  23.  
  24. class ClientsController < ApplicationController
  25. def show
  26. @client = Client.find(params[:id])
  27. end
  28. def edit
  29. @client = Client.find(params[:id])
  30. end
  31. def update
  32. @client = Client.find(params[:id])
  33. if @client.update_attributes(client_params_edit)
  34. flash[:success] = "Profile Updated"
  35. redirect_to @client
  36. else
  37. flash[:failure] = "Profile Information Invalid"
  38. render 'edit'
  39. end
  40. end
  41. def client_params_edit
  42. params.require(:client).permit(:avatar,:industry,:city,:website,:description)
  43. end
  44. end

提供者控制器非常相似.

最后,这是我的schema.rb:

  1. ActiveRecord::Schema.define(version: 20140628213816) do
  2.  
  3. create_table "disciplines",force: true do |t|
  4. t.integer "years"
  5. t.string "description"
  6. t.integer "user_id"
  7. end
  8.  
  9. create_table "users",force: true do |t|
  10. t.string "name"
  11. t.string "email"
  12. t.string "avatar_file_name"
  13. t.string "avatar_content_type"
  14. t.integer "avatar_file_size"
  15. t.datetime "avatar_updated_at"
  16. t.string "password_digest"
  17. t.string "industry"
  18. t.string "city"
  19. t.string "state"
  20. t.string "website"
  21. t.string "description"
  22. t.string "encrypted_password",default: "",null: false
  23. t.string "reset_password_token"
  24. t.datetime "reset_password_sent_at"
  25. t.datetime "remember_created_at"
  26. t.integer "sign_in_count",default: 0,null: false
  27. t.datetime "current_sign_in_at"
  28. t.datetime "last_sign_in_at"
  29. t.string "current_sign_in_ip"
  30. t.string "last_sign_in_ip"
  31. t.datetime "created_at"
  32. t.datetime "updated_at"
  33. t.string "type"
  34. t.string "ptype"
  35. t.string "education"
  36. t.string "resume_file_name"
  37. t.string "resume_content_type"
  38. t.integer "resume_file_size"
  39. t.datetime "resume_updated_at"
  40. end
  41.  
  42. add_index "users",["email"],name: "index_users_on_email",unique: true
  43. add_index "users",["reset_password_token"],name: "index_users_on_reset_password_token",unique: true
  44.  
  45. end

解决方法

您需要指定在自定义注册控制器(从Devise :: RegistrationsController继承的)中实例化哪个模型.

您必须覆盖名为resource_class的受保护方法有点像这样:

  1. def resource_class
  2. # for example you pass type inside params[:user]
  3. klass = params[:user].try(:[],:type) || 'Client'
  4. # we don't want wrong class to be instantiated
  5. raise ArgumentError,'wrong user class' unless ['Client','Provider'].include?(klass)
  6. # transform string to class
  7. klass.constantize
  8. end

此外,您也可能希望覆盖sign_up_params以根据用户类型指定允许的参数.

猜你在找的Ruby相关文章