如何让Angular与Rails路由很好地配合?

时间:2015-07-22 02:41:05

标签: ruby-on-rails angularjs devise routes angular-routing

我正在使用Rails 4.2.3,Devise和AngularJS。我已经设置了Devise,它将接受并呈现JSON,而我的其他Rails应用程序几乎只是一个API,它也在响应中呈现JSON。

我的Angular配置如下:

angular.module('beer', ['ngRoute']).
    config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/beers', {
            templateUrl: "../templates/beers.html",
            controller:  "BeersCtrl"
        }).otherwise({
            templateUrl: "../templates/login.html",
            controller:  "LoginCtrl"
        });
    });

我遇到的问题是,如果某人访问了某个网址且会话已过期,则Devise会重定向到/users/sign_in以让他们登录。如果访问过的原始网址类似http://localhost:3000/#/beers且未经过身份验证,则设计重定向到http://localhot:3000/users/sign_in/#/beers

重定向导致Angular仍然看到/beers路由,因此不会呈现登录页面。我不确定如何让Rails或Angular了解彼此的URL并正确处理它们。

例如,有没有办法让Rails重定向到像http://localhost:3000/#/users/sign_in这样的东西,或者有一些方法让Angular看到http://localhost:3000/users/sign_in并且知道它应该加载LoginCtrl?或者,有什么我想念的东西会让整个事情变得更容易实现吗?

1 个答案:

答案 0 :(得分:0)

@charlietfl在我的问题评论中给了我一些暗示。我最后做的是重新组织我的Rails路线。我将设计内容和我的BeersController放在命名空间中,任何不访问该命名空间内容的路由都会被重定向到带有哈希的索引页面。

例如;如果用户访问/beers,则路由路由将捕获该路由并将其更改为/m/#/beers/m/映射到我的Rails路由中的application#index

因此,我的Rails routes.rb文件如下所示:

Rails.application.routes.draw do
    namespace :api do
        devise_for :users, :controllers => {
            sessions: 'sessions',
            registrations: 'registrations'
        }
        resources :beers
    end

    root 'application#index'

    get '/m/' => 'application#index'
    get '*path' => redirect('/m/#/%{path}')
end

我的Angular路线看起来一样。

旁注: 出于某些奇怪的原因,我无法让redirect('/')工作。看起来好像在Rails 4.2.3中,只使用/作为redirect的参数没有做任何事情因为某些原因它并不认为它引用了绝对URI这样做。因此,例如,如果用户转到http://blah.com/cats/meow,则Rails重定向将仅重定向到相同的URL。我希望它能重定向到http://blah.com/,但事实并非如此。

此外:如果您在尝试发布并重新获得JSON时遇到了Devise的问题,请确保您已发布到/api/users/sign_in.json并且您的有效负载看起来像:

api_user: {
    email: 'email',
    password: 'password'
}

这让我陷入了一个循环,因为我并不期望有效负载需要随命名空间而改变。