Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to use Rails 3 + Angular.js, but when I try to send a post request with angular.js to Rails, the controller lost the current_session.

This is the workflow through my application.

1. Login with devise (Only use the rails way)

2. The application is redirect to crear_perfil.html (This is an angular.js view)

This is my app.js

//= require angular
//= require angular-animate
//= require angular-resource
//= require angular-route
//= require angular-touch
//= require_tree ./angular/models
//= require_tree ./angular/controllers
//= require_tree ./angular/directives
//= require underscore-min
//= require angular-google-maps.min

app = angular.module('squapeApp', ['ngAnimate' , 'ngRoute', 'ngResource','PublicationService','PersonService','appCtrl', 'google-maps', 'ngTouch']);

app.config(['$routeProvider','$locationProvider', 
    function($routeProvider,$locationProvider){
        $routeProvider.
        when('/publicaciones',{
            templateUrl: '../assets/index.html',
            controller: 'PublicationCtrl'
        }).
        when('/informacion/perfil',{
            templateUrl: '../assets/crear_perfil.html',
            controller: 'ProfileCtrl'
        }).
        otherwise({
            redirectTo: '/publicaciones'
        });

        $locationProvider.html5Mode(true);
}]);

And this is my angular view for this step:

<form name="profileForm" ng-submit="profileForm.$valid && submitForm()" novalidate>
 <input class="text input" type="text" placeholder="Nelson Patricio" id="nombre" ng-model="person.name" required/>
 <input type="submit" name="" value="Guardar" ng-disabled="profileForm.$invalid">
</form>

3. Fill out the field and submit the form to angular.js controller ( ProfileCtrl )

This is my appCtrl.js (this file content my ProfileCtrl )

var app = angular.module("appCtrl", []);

app.controller('ProfileCtrl', ['Person','$scope','$http', function(Person, $scope, $http){
  $scope.angularClass = "e-profile";
  $scope.person = new Person();
  $scope.persona = Person.query();

  $scope.submitForm = function(){
    if ($scope.profileForm.$valid) {
      console.log("waiting for save");
      $scope.person.$save();
      console.log("save it");
    }
  };

}]);

4. The ProfileCtrl call the Person factory

var person = angular.module('PersonService', []);

person.factory('Person', ['$resource', function($resource){

    var Person = $resource(
    'http://squape.dev/perfil/:id.json', 
    {id: '@id'}, {
        update: {
            method: 'PUT'
        },
        query:{
            isArray: false
        }
    });



    return Person;

}]);

5. The Person Factory call the rails controller (ProfileController)

class ProfileController < ApplicationController
  respond_to :json  

  def index
    @person = current_user.person
    respond_with @person
  end

  def create
    @person = current_user.build_person(params[:person])
    if @person.save
      respond_with @person, location: root_path
    end
  end

  def update
    redirect_to root_path
  end

  def informacion
    @user = current_user
    @user.build_person if @user.person.nil?
  end
end

When I send the angularjs FORM (angularjs send a POST request so the create method is called in the rails controller) my curren_session is nil, but if a I call the angular query method (angularjs send a GET request so the index method is called in the rails controller) the current_user is a good object.

Why the create method in rails controller return a current_user = nil when I send a POST request ?

I really appreciate your advice.

regards,

UPDATE *******

The problem is solved, the current_user is nil because I'm not sending X-CSRF-Token, for solved this in my app.js add this.

$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');

app = angular.module('squapeApp', ['ngAnimate' , 'ngRoute', 'ngResource','PublicationService','PersonService','appCtrl', 'google-maps', 'ngTouch']);

app.config(['$routeProvider','$locationProvider', '$httpProvider', 
    function($routeProvider,$locationProvider, $httpProvider){

        $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');

        $routeProvider.
        when('/publicaciones',{
            templateUrl: '../assets/index.html',
            controller: 'PublicationCtrl'
        }).
        when('/informacion/perfil',{
            templateUrl: '../assets/crear_perfil.html',
            controller: 'ProfileCtrl'
        }).
        otherwise({
            redirectTo: '/publicaciones'
        });

        $locationProvider.html5Mode(true);
}]);

but now the controller create a void object. For any reason isn't receiving the name and the last_name

enter image description here

share|improve this question
1  
I guess its because you dont send the authenticity token –  apneadiving May 29 at 7:28
    
Thanks a lot, I add X-CSRF-Token and the POST request is accepted, but now I have problems with the params in the controller. The controller is creating nil object –  Nelson Patricio Jimenez May 29 at 7:46
add comment

1 Answer

up vote 1 down vote accepted

Yes, CSRF token is missing and cause this problem. I recommend to use ng-rails-csrf gem to do it for you.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.