【问题标题】:Creating two types of users Rails app创建两种类型的用户 Rails 应用程序
【发布时间】:2015-02-26 22:49:25
【问题描述】:

我正在创建一个具有两种用户类型的 Rails 应用:司机和机械师。

到目前为止,我已经完全设置了司机类(称为“用户”),其中包含连接“汽车”模型的配置文件和属性,以便他们可以将汽车添加到他们的配置文件中。

现在我需要创建类似于商业页面的“机械师”用户,包括地址、提供的服务等,然后这些机械师会将司机添加为他们的客户。

我的直觉是创建一个新的机制模型,并以与我创建用户模型相同的方式设置它,但具有适当的架构。我想我可能会遇到sessions helper 的问题,因为很多功能都使用了“用户”。我可以在会话助手中复制这些项目并将“用户”替换为“机械师”,但我不确定这是否可行。

我考虑过使用像 cancancan 这样的 gem 来限制用户,但这似乎有问题。还想知道我是否可以使用当前的“用户”类并创建另外两个从用户继承的模型(驱动程序和机制),每个模型都有特定的功能。

我真的需要知道从哪个方向开始才能实现这一点,所以任何建议、有用的 rails casts 的链接等都会令人惊叹。谢谢!

会话助手

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

  # Remembers a user in a persistent session.
  def remember(user)
    user.remember
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end

  def current_user?(user)
    user == current_user
  end

  # Returns the user corresponding to the remember token cookie.
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end

  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end

  # Logs out the current user.
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end

  # Redirects to stored location (or to the default).
  def redirect_back_or(default)
    redirect_to(root_url)
    session.delete(:forwarding_url)
  end

  # Stores the URL trying to be accessed.
  def store_location
    session[:forwarding_url] = request.url if request.get?
  end
end

user.rb

class User < ActiveRecord::Base
  has_many :cars
  attr_accessor :remember_token
  before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :phone, presence:true
  validates :password, length: { minimum: 6 }, allow_blank: true

  # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  # Returns a random token.
  def User.new_token
    SecureRandom.urlsafe_base64
  end

  # Remembers a user in the database for use in persistent sessions.
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # Returns true if the given token matches the digest.
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

  def forget
    update_attribute(:remember_digest, nil)
  end

  def feed
    Car.where("user_id = ?", id)
  end
end
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
      end

      def current_user?(user)
        user == current_user
      end

      # Returns the user corresponding to the remember token cookie.
      def current_user
        if (user_id = session[:user_id])
          @current_user ||= User.find_by(id: user_id)
        elsif (user_id = cookies.signed[:user_id])
          user = User.find_by(id: user_id)
          if user && user.authenticated?(cookies[:remember_token])
            log_in user
            @current_user = user
          end
        end
      end

      # Returns true if the user is logged in, false otherwise.
      def logged_in?
        !current_user.nil?
      end

      def forget(user)
        user.forget
        cookies.delete(:user_id)
        cookies.delete(:remember_token)
      end

      # Logs out the current user.
      def log_out
        forget(current_user)
        session.delete(:user_id)
        @current_user = nil
      end

      # Redirects to stored location (or to the default).
      def redirect_back_or(default)
        redirect_to(root_url)
        session.delete(:forwarding_url)
      end

      # Stores the URL trying to be accessed.
      def store_location
        session[:forwarding_url] = request.url if request.get?
      end
    end

【问题讨论】:

    标签: ruby-on-rails ruby session rails-models


    【解决方案1】:

    我建议通过将身份验证与授权分开来稍微不同地考虑您的设置。用户、驾驶员和机械师是独立但相关的概念。用户是可以访问您的应用程序机制的任何人,驱动程序是分配给用户的角色(他们有权执行的操作)。

    有多种不同的方法可以解决这个问题,而且不知道您的应用程序的确切性质,很难提出一个特定的解决方案,但我认为,如果您解决这些问题,那么从长远来看,您的情况会好很多运行。

    这是一个很好的资源链接,可以帮助您入门:

    http://railsapps.github.io/rails-authorization.html

    【讨论】:

      【解决方案2】:

      使用 cancan gem .. 你可以在 railscasts.com 找到它的一集

      【讨论】:

      • rails 4 不支持 cancan。
      【解决方案3】:

      我认为,devise gem 应该会有所帮助。

      查看入门部分 (https://github.com/plataformatec/devise/blob/master/README.md#getting-started),您可以在其中找到如何创建不同类型用户的信息。

      希望有帮助!

      【讨论】:

        【解决方案4】:

        查看 Pundit gem:https://github.com/elabs/pundit 我在最近的一个项目中使用它并喜欢它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-03-05
          • 2016-12-02
          • 1970-01-01
          • 2023-01-21
          • 2014-10-26
          • 2021-12-02
          • 2017-04-07
          相关资源
          最近更新 更多