【问题标题】:When using devise in rails, how do I add two different types of users that will use the site in two different ways?在 Rails 中使用设计时,如何添加两种不同类型的用户,它们将以两种不同的方式使用该站点?
【发布时间】:2016-04-05 00:24:59
【问题描述】:

我正在构建一个工作委员会应用程序。我是编程新手,正在自学 Rails 框架。

我正在使用 Devise 进行身份验证。我将有两种不同类型的用户; Job SeekerEmployer。求职者将创建个人资料并搜索职位发布,而雇主将创建公司简介并发布职位列表。将来,雇主也可以根据资格、经验、教育等来寻找员工,但现在我只是在构建我的 MVP。

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-4 authentication devise


【解决方案1】:

这种类型的功能很棘手,即因为您必须在实现之前放置功能(IE 大多数人对Devise 很感兴趣,而它可能根本没有功能)


你有两种方法:

Devise 是一个身份验证系统(用户登录);您可能会更好地使用授权(用户可以执行 x 或 y)。授权超出了 Devise 的范围。

虽然您可以使用多个模型(Devise),但我认为它会为您的需要造成太多不必要的膨胀。

相反,我会使用一个非常简单的角色系统(使用enum):

#app/models/user.rb
class User < ActiveRecord::Base
   enum role: [:job_seeker, :employer]

   has_one :profile
   before_create :build_profile

   has_many :applications
   has_many :listings, through: :applications
end

#app/models/application.rb
class Application < ActiveRecord::Base
    belongs_to :listing
    belongs_to :user
end

#app/models/listing.rb
class Listing < ActiveRecord::Base
   has_many :applications
   has_many :applicants, through: :applications, class_name: "User", foreign_key: :user_id
end

您需要将 role 列 (int) 添加到您的 users 表中。您将在创建列时使用 default: [x] 开关创建 default 角色:

def change
   add_column :users, :role, :integer, default: 0 #-> defaults to job seeker
end

--

您已经描述了几个非常适合这一点的因素:

  • Job seeker 将创建个人资料
  • Employer 将创建个人资料并发布列表

...这意味着您的"flow" 对于两种用户类型都将保持相似。您只需要管理每个用户可以使用授权做什么。


设置

#config/routes.rb
resource  :profile, controller: :users, only: [:show, :update] #-> url.com/profile
resources :listings, only: [:show] do
   post :apply, on: :member #-> url.com/listings/:id/apply
end
resources :companies, controller: :users, only: [:show]

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   #show will automatically be loaded

   def update
      current_user.update profile_params
   end

   private

   def profile_params
      params.require(:user).permit(profile_attributes: [:name, :etc, :etc])
   end
end

#app/views/users/show.html.erb
<%= form_for current_user do |f| %>
   <%= f.fields_for :profile do |p| 
      <% if current_user.job_seeker? %>
         <%= f.text_field :name, placeholder: "Your name" %>
      <% elsif current_user.employer? %>
         <%= f.text_field :name, placeholder: "Company name" %>
      <% end %>
   <% end %>
   <%= f.submit %>
<% end %> 

然后您就可以使用以下内容来检查用户是否可以创建列表,或者只是查看:

#app/controllers/listings_controller.rb
class ListingsController < ApplicationController
   before_action :check_seeker, only: [:apply]
   before_action :check_employer, only: [:new, :create, :destroy]

   def new  #-> employers
      @listing = current_user.listings.new
   end

   def apply #-> job seekers
      @listing     = Listing.find params[:id]
      @application = current_user.applications.new
      @application.listing = @listing
      redirect_to @listing, notice: "Application successful!" if @application.save 
   end

   private

   def check_seeker
      redirect_to listings_path, notice: "Only Job Seekers Allowed" unless current_user.job_seeker?
   end

   def check_employer
      redirect_to root_url, notice: "Only Employers Allowed" unless current_user.employer?
   end
end

希望这可以为您提供要点。


设计

要让 Devise 使用您的新专栏,您需要 extend the Devise Sanitizer:

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :role
  end
end

这将允许您在注册时更改 role 字段:

#app/views/devise/registrations/new.html.erb
.....
  <%= f.select :role, User.roles %>

【讨论】:

  • Rich,非常感谢您的评论。这里有很多很好的信息,肯定会帮助我构建我的应用程序。感谢您采取类型解释并为您的解释提供示例!绝对赞赏!
  • Rich,我如何将它与 Devise 一起使用。我添加了角色迁移。在我的应用程序标题中,用户有一个名为“注册”的下拉菜单,其中包含两个字段,求职者和雇主。这将是他们做出选择的地方,所以我不会有默认值。我将如何修改您的代码以匹配此偏好?
  • 用户模型是否有role_id属性?
  • 没有。我刚刚在 Devise 的 Wiki 中找到了我认为可以帮助我做到这一点的文档。我只需要回滚我已经进行的迁移。
  • 好的,如果您进行回滚,请告诉我它是否有效;如果没有,我会在这里帮助你
【解决方案2】:

Devise 适用于身份验证,但对于角色和访问控制,您可能需要查看 Rolify:https://github.com/RolifyCommunity/rolify

这将允许您保持单一用户模型并使用角色查询控制对不同功能的访问,即:

unless current_user.has_role?(:admin)
  redirect_to ...
else
  render ...
end 

【讨论】:

  • 太棒了,谢谢推荐。这将极大地简化我的事情。 rolify 是否提供身份验证,还是我会将 Rolify 与 Devise 一起使用?
  • 您将使用 rolify 和设计。您也可以将 Rolify 与其他身份验证框架一起使用,但我已成功将其与 devise 一起使用,并且对结果非常满意。
【解决方案3】:

对于角色,您可以将CanCanCan gem 和RoleModel gem 与devise 一起使用,这对于具有不同角色的用户来说会更好。

CanCanCan

Defining abilities using cancancan

Role model gem

Example for user roles with above gems..

【讨论】:

    猜你喜欢
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2012-01-03
    相关资源
    最近更新 更多