ruby-on-rails - AngularJS:将设计与多个模型一起使用

标签 ruby-on-rails angularjs ruby-on-rails-4 devise

我有一个 Rails 应用程序,它使用了两个不同的模型,对应于截然不同的 Angular 色(没有 STI - 完全不同的模型)。

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

以下是我的初步想法:

  • 每个用户模型都有不同的基础登录页面(domain.com/user 和 domain.com/company)
  • 在呈现该页面之前,我检查是否正确的 Angular 色已登录,使用设计,如果没有重定向到相应的登录页面(服务器端重定向)
  • 所有未登录的页面都是非 Angular 的,这样才能有效地发生这种情况。
  • 登录的页面都是 Angular-ified

  • 这确保了我不必担心如何让 angular 和 design 一起工作。在一个模块中,我可以确定有一个登录用户(或公司)

    请建议这听起来是否不错。

    另外,如果有(不太复杂)整个应用程序可以使用 Angular 的方式,我会更喜欢。 (登录重定向到相应的登录页面等)。我已经看到了一些以服务模块等形式出现的 Angular + Devise 示例,但几乎所有这些示例似乎都只适用于一种模型。

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

    最佳答案

    构建一个两头的 Auth Monster

    所以你所描述的是可能的,但肯定会很痛苦。您将不得不构建一堆代码来确定用户是否是 Rails 端的 NormalUser 和 AdminUser。在 Angular 方面,您必须确定用户需要哪个登录名,NormalUser 与 AdminUser。话虽如此,这是可能的,这里有一些应该有所帮助的指针。

    文档是您的 friend

    You really really really want to have a good understanding of how Devise works.设计在幕后做了很多魔术。

    授权使用 Angular ,您需要熟悉 $httpProvider.interceptors , Services , 和 Resources .

    rails

    路线

    在设计中有两个模型的示例路线:

    devise_for :normal_users
    
    devise_for :admin_users
    
    # route for the sample controller below
    resource :users do
      collection do
        get :current
      end
    end
    

    Devise 带来了什么

    设计将创建 helper methods在您的 Controller 中,大致如下:
    current_normal_user
    
    authenticate_normal_user!
    
    current_admin_user
    
    authenticate_admin_user!
    

    因此,您必须检查两者以查看 session 是否已通过身份验证,最好的计划是将这两个检查包装到自定义 before_action ,类似于before_action :authenticate_all_users .

    用户示例 Controller

    这是一个示例 UsersControllers返回 JSON Angular 将用于检查身份验证。
    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

    安全网

    在 Angular 中处理身份验证时,我发现这个拦截器非常有用。将此添加到您的 app.config在设置 Angular 时,如果任何 http 请求返回 401 状态码,它将重定向到指定页面。这比强制所有资源处理用户未通过身份验证的可能性要简单。 (作为咖啡师)

    # Monitors the requests and responses of angular
    #  * Redirects to /users/sign_in if status is a 401
    app.config [
      "$httpProvider"
      ($httpProvider) ->
        $httpProvider.interceptors.push ($q) ->
          request: (config) ->
            config or $q.when(config)
    
          requestError: (rejection) ->
            $q.reject rejection
    
          response: (response) ->
            response or $q.when(response)
    
          responseError: (rejection) ->
    
            # Not logged in, redirect to login
            if rejection.status is 401
              $q.reject rejection
    
               # Change this with desired page
              window.location = "/users/sign_in"
    
            else
              $q.reject rejection
    

    在您的场景中,您可能需要添加逻辑来确定他们应该看到哪个登录页面,normal_user 与 admin_user。

    用户信息

    最后是一个获取用户信息的示例 Angular 服务。如果用户没有被认证,401状态会被之前的$httpProvider抓到并对用户进行相应处理。否则,如果用户通过了身份验证,用户的信息将填充到 $rootScope.currentUser .您只需将其作为依赖项添加到应受身份验证保护的 Controller 中。 (在 CoffeeScript 中)
    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
    

    该服务依赖于 CurrentUser指向 /users/current.json 的资源端点。在您使用 CurrentUserService 的场景中,处理多个模型的可能选项是:
  • 检查用户是否已通过身份验证,一次用于 normal_user,一次用于 admin_user
  • 创建一个自定义 Controller 方法来检查 normal_user 和 admin_user 的身份验证,这大致是示例 rails Controller 正在做的事情。

  • 额外学分

    或者,我会查看 ng-idle作为允许 session 在 Angular 中过期的一种方式。

    从评论更新

    My logged in page starts displaying while the backend request for user info is happening, and consequently the redirect to login page is quite visible and leads to a bad ux.



    最简单的方法是使用非 Angular 页面进行登录,例如 Devise 提供的页面。一旦用户成功登录,他们被定向到的页面就会加载 Angular 应用程序。这样,您始终可以假设用户在使用 Angular 时已登录。

    如果这不可能,您将不得不从 Angular 发出身份验证请求。这意味着您需要让用户等待,直到您可以从身份验证请求中检查 promise 。一旦它有效,您将用户移动到正确的路线。

    警告 如果您无法登录,我相信 Devise 会发送一个状态码 401,这将使前面讨论的拦截器跳闸。为了解决这个问题,拦截器必须排除处理身份验证请求的路径。

    用于处理 Auth 的示例资源:
    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
    )
    

    关于ruby-on-rails - AngularJS:将设计与多个模型一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23995615/

    相关文章:

    ruby-on-rails - 如何在创建时使用主键的值设置另一列

    javascript - 从 $http.get JSON 调用中删除关键字

    ruby-on-rails - 设计重置密码。不重定向,发回Ajax成功?

    ruby-on-rails - Friendly_id 为现有模型创建 slug

    Mysql2 'individual' 中的未知列 'field list'

    ruby-on-rails - 找不到: syntax error, unexpected '>' in ROR app的原因

    javascript - 带数组的反向查找对象

    ruby-on-rails - stub 模型常量以进行关联(未定义方法 `relation_delegate_class' )

    ruby-on-rails - 如何测试使用 puntopagos 和 rest-client 的 Controller Action ?

    javascript - 使用 Angular + aws-sdk-js + 预签名 url 将文件上传到 S3