【问题标题】:Can I use CanCan with model(s) other than User?我可以将 CanCan 与用户以外的模型一起使用吗?
【发布时间】:2014-07-24 21:05:34
【问题描述】:

我是 Rails 新手,我是使用 api 上的数据构建应用程序的新手,我有两个表要供用户使用 - studentseducators

我可以在控制器中进行身份验证

private

def fetch_user_data(username, password)

    require 'URI'

    uri = URI('the url for the api')
    res = Net::HTTP.post_form(uri, 'username' => username, 'password' => password)
    xml = res.body
    doc = Nokogiri::Slop(xml)

    @status = doc.auth.status.content.to_s
    @username = doc.auth.username.content.to_s
    @token = doc.auth.token.content.to_s
    @person_id = doc.auth.person_pk.content.to_i
    @security_roles = doc.auth.security_roles.content.to_s.downcase
end

def assign_user

    if /faculty/ =~ @security_roles
        @user = Educator.find_by(person_id: @person_id)
    elsif /student/ =~ @security_roles
        @user = Student.find_by(person_id: @person_id)
    end
end

def authenticate_user(username, password)

    fetch_user_data(username, password)
    assign_user
    session[:user_id] = @user.id 
    redirect_to @user 
end

现在我知道它可能不漂亮,但我边走边学。我在会话控制器中使用authenticate_user(),并且基于重定向,身份验证似乎很好。我确实对会话中的:user_id 键有一个疑问——该键是仅为会话创建的,还是试图从用户表中提取值?知道这会有所帮助。我的猜测是它只是为会话创建的,但我不知道。

好的,现在解决我真正的问题。我正在尝试使用 cancan,但我在定义当前用户时遇到了困难。

我想我可以让@current_user 实例指向我在assign_user 中分配的@user。不过,这似乎不起作用。我尝试了几件事,但我被卡住了。也许我什至不能这样做?更大的问题?我是否必须有一个用户模型才能使 cancan 工作?我可以使用 Educators 和 Student 这两个模型,并在它们上屏蔽 cancan 中的用户引用吗?

我试过了,但它不起作用——有什么帮助吗?

def current_user
    @current_user ||= @user
end

编辑: 想通了一点。 1.方法在ApplicationHelper。将 current_user() 移至 ApplicationController 。将语法更改为常规语法,但添加了条件。

def current_user
 if Student.where(id:session[:user_id]).count == 0
     @current_user ||= Educator.find(session[:user_id])
 else
     @current_user ||= Student.find(session[:user_id])
 end
end

这似乎可以解决问题,并允许我将两个表都用作用户模型。

【问题讨论】:

    标签: ruby-on-rails ruby authentication models cancan


    【解决方案1】:

    定义 current_user 的方法有多种(如果您不使用 Devise),但这个 here 非常标准:

    class ApplicationController < ActionController::Base
      def current_user
        @current_user ||= User.find(session[:user_id])
      end
    end
    

    至于您关于会话的问题,您设置会话的方式,您将 session[:user_id] 设置为等于 @user.id(对于每个用户来说始终相同)。

    【讨论】:

    • 没问题。如果它有助于解决您的问题,请投票/接受此答案。干杯。
    • 您应该在尝试设置@current_user 之前添加return unless session[:user_id]。没有它,每次if current_user 在退出时检查都会触发另一个数据库查询
    【解决方案2】:

    考虑使用宝石 CanCanCan ,就像它听起来的那样。 CanCan 无法维护,并且有人设置了替代 CanCanCan。您无需更改任何代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 2021-03-17
      • 2015-11-30
      相关资源
      最近更新 更多