Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails AngularJS:与多个模型一起使用Desive_Ruby On Rails_Angularjs_Ruby On Rails 4_Devise - Fatal编程技术网

Ruby on rails AngularJS:与多个模型一起使用Desive

Ruby on rails AngularJS:与多个模型一起使用Desive,ruby-on-rails,angularjs,ruby-on-rails-4,devise,Ruby On Rails,Angularjs,Ruby On Rails 4,Devise,我有一个rails应用程序,使用Desive,有两个不同的模型,对应着完全不同的角色(没有STI-完全不同的模型) 我打算搬到前端的AngularJS。想知道构建应用程序的最佳方式是什么 以下是我的初步想法: 每个用户模型都有不同的基本登录页面(domain.com/user和domain.com/company) 在呈现该页面之前,我使用Desive检查是否已登录正确的角色,如果没有,则重定向到相应的登录页面(服务器端重定向) 所有未登录的页面都是非角度的,以便有效地执行此操作 已登录的页面都

我有一个rails应用程序,使用Desive,有两个不同的模型,对应着完全不同的角色(没有STI-完全不同的模型)

我打算搬到前端的AngularJS。想知道构建应用程序的最佳方式是什么

以下是我的初步想法:

  • 每个用户模型都有不同的基本登录页面(domain.com/user和domain.com/company)
  • 在呈现该页面之前,我使用Desive检查是否已登录正确的角色,如果没有,则重定向到相应的登录页面(服务器端重定向)
  • 所有未登录的页面都是非角度的,以便有效地执行此操作
  • 已登录的页面都是透明的
  • 这确保了我不必担心如何使angular和Desive协同工作。在一个模块中,我可以确保有一个登录的用户(或公司)

    如果这听起来不错,请提出建议

    另外,我更希望整个应用程序能够使用Angular(不太复杂)的方式。(登录重定向到相应的登录页面等)。我见过一些以服务模块等形式出现的Angular+Desive的示例,但几乎所有这些示例似乎只适用于一种模型


    编辑:理想情况下,我希望能够尽可能多地使用Desive的功能。

    我建议您重新思考您的问题,假装Desive和angular彼此无关

    假设您不打算在rails中呈现任何html模板。您只需要使用rails创建一个json api,应用程序的接口将是一个单页应用程序。UI路由都将在angular应用程序中完成

  • 在angular应用程序中创建登录路径时,它有一个表单指向服务器的设计登录路径/api/v1/user/sign-in
  • 当用户点击表单上的submit时,angular可以执行一些前端验证并将数据发送到服务器
  • 在rails控制器中,Desive将验证此人的身份,在Desive验证他们之后,服务器路由应将用户信息作为json响应(或错误消息)发回
  • 向Desive端点发出请求的angular服务现在可以访问用户信息(从服务器的json响应)。它可以检查这个用户对象的属性,比如他们的角色,然后它可以使用angular的位置服务来改变这个角色应该去哪里的路由

    当路线改变角度时,将呈现路线的视图,一切都将继续进行

    如果需要根据角色更改路由内的UI,请参见此问题

    当用户稍后返回您的站点时,您可以让angular应用程序检测到他们仍在登录。您为用户登录而编写的angular服务也可以负责尝试获取当前用户,如果没有,则重定向到登录页面

    Desive为您提供了一个名为current_user的助手,该助手将允许您访问已登录用户的实例。您应该创建一个像/api/v1/current_user这样的服务器路由,并让它返回用户信息。如果用户已登录,请像登录后一样重定向到其主页。否则重定向到登录页面

    如果你不太了解angular,我建议你花点时间在这个网站上

    此外,您可能需要在服务器上实现授权逻辑

    构建双头身份验证怪物 所以你所描述的是可能的,但这肯定是一种痛苦。在Rails端,您必须构建一组代码来确定用户是NormalUser还是AdminUser。在角度方面,您必须确定用户需要哪个登录,NormalUser与AdminUser。也就是说,这是可能的,这里有一些建议应该会有所帮助

    医生是你的朋友 Desive在幕后发挥了很多魔力

    要使用auth,您需要熟悉和

    轨道 路线 在Desive中具有两个模型的示例路线:

    devise_for :normal_users
    
    devise_for :admin_users
    
    # route for the sample controller below
    resource :users do
      collection do
        get :current
      end
    end
    
    什么样的设计能带来成功 Desive将在控制器中创建以下内容:

    current_normal_user
    
    authenticate_normal_user!
    
    current_admin_user
    
    authenticate_admin_user!
    
    因此,您必须检查这两个检查以查看会话是否已通过身份验证,最好的计划是在\u操作之前将这两个检查包装成自定义的
    ,类似于\u操作之前的
    :对所有用户进行身份验证

    用户控制器示例 下面是一个示例
    UsersController
    ,它返回用于检查身份验证的JSON

    class UsersController < ApplicationController
      # Needs a before_action that authenticates the user
    
      respond_to :json
    
      def current
        @user = current_normal_user || current_admin_user
    
        respond_with @user
      end
    
    end
    
    在您的场景中,您可能需要添加逻辑来确定他们应该看到哪个登录页面,普通用户还是管理员用户

    用户信息 最后是一个获取用户信息的示例Angular service。如果用户未通过身份验证,则先前的
    $httpProvider
    将捕获401状态,并相应地处理该用户。否则,如果用户经过身份验证,则用户信息将填充到
    $rootScope.currentUser
    。您只需将其作为依赖项添加到应该受身份验证保护的控制器中。(用咖啡脚本)

    此服务依赖于指向
    /users/current.json
    端点的
    CurrentUser
    资源。在使用CurrentUserService的场景中,处理多个模型的可能选项有:

    • 检查两次用户是否经过身份验证,一次是普通用户,另一次是管理员用户
    • 创建一个自定义控制器方法来检查普通用户和管理员用户的身份验证,这大致就是示例rails控制器所做的
    额外学分 或者,我会研究一种允许会话在Angular内过期的方法


    根据评论更新 当后端请求用户信息为hap时,我的登录页面开始显示
    angular.module("TheAngularApp.services").service "CurrentUserService", ($rootScope, $http, CurrentUser, User) ->
        userService =
            reloadCurrentUser: ->
                @currentUser = CurrentUser.show((user) ->
                    # set in scope
                    $rootScope.currentUser = user
                )
                @currentUser
    
        userService.reloadCurrentUser()
        userService
    
    Session.create {email: email, password: password}, success = (user) ->
       # User was successfully authenticated
       $scope.currentUser = user
       $location.path( "/" );  
    , error = (data, status, headers, config) ->
       # Failed to auth, notify user
    )