如何将Angular表单保存到rails后端的ruby上?

时间:2015-02-09 02:35:22

标签: ruby-on-rails angularjs forms

我是Angular的新手。我已经尝试了我所知道的一切,谷歌搜索在这个特定问题上的教程很少。这是我试过的最后一个代码:

的index.html

<form ng-submit="addArticle(articles)">
<input type="text" id="title" ng-model="newPost.title">
<input type="text" id="body" ng-model="newPost.body">
<input type="submit" value="Submit">
</form>
文章控制器

app.controller('ArticlesCtrl', function($scope, Article) {
  $scope.articles   = Article.query();
  $scope.newPost     = Article.save();
});

文章服务(rails后端)

app.factory('Article', function($resource) {
  return $resource('http://localhost:3000/articles');
});

我可以很好地检索数据。但是我无法向rails后端提交任何新数据。在页面加载时,rails服务器错误是:

Started POST "/articles" for 127.0.0.1 at 2015-02-08 18:26:29 -0800
Processing by ArticlesController#create as HTML
Completed 400 Bad Request in 0ms

ActionController::ParameterMissing (param is missing or the value is empty: article):
  app/controllers/articles_controller.rb:57:in `article_params'
  app/controllers/articles_controller.rb:21:in `create'

按提交按钮什么都不做。表单基本上不起作用,页面在加载后立即查找提交。

我理解错误说的是,它没有从表单中接收参数。我不明白的是我的控制器和/或表格应该是什么样的。

我做错了什么以及如何解决这个问题?

3 个答案:

答案 0 :(得分:7)

Angular有一个名为services的功能,它充当应用程序的模型。这是我与Rails后端通信的地方:

服务/ article.js

app.factory('Article', function($resource) {
  return $resource('http://localhost:3000/articles/:id', { id: '@id'},
  {
   'update': { method: 'PUT'}
  });
});

即使最后指定了:id,它也可以直接进入/articles路径。 id仅在提供的地方使用。

其余工作进入控制器:

控制器/ articles.js

app.controller('NewPostCtrl', function($scope, Article) {
  $scope.newPost  = new Article();

  $scope.save = function() {
    Article.save({ article: $scope.article }, function() {
      // Optional function. Clear html form, redirect or whatever.
    });
  };

});

最初,我认为通过save()提供的$resources功能有些自动化。它是,但我错了。默认的save()函数最多可以使用四个参数,但似乎只需要将数据传递给数据库。在这里,它知道向我的后端发送POST请求。

视图/物品/ index.html中

<form name="form" ng-submit="save()">
    <input type="text" id="title" ng-model="article.title">
    <input type="text" id="body" ng-model="article.body">
    <input type="submit" value="Submit">
</form>

正确设置service后,剩下的工作很简单。在控制器中,需要创建资源的新实例(在本例中为新文章)。我创建了一个新的$scope变量,其中包含调用我在save中创建的service方法的函数。

请记住,可以根据需要为服务中创建的方法命名。它们的重要性在于发送的HTTP请求的类型。对于任何RESTful应用程序尤其如此,因为GET请求的路由与POST请求的路由相同。

以下是我找到的第一个解决方案。再次感谢您的回复。他们在我的实验中有助于了解它是如何工作的!

原始解决方案: 我终于修好了,所以我会发布我的特定解决方案。但是,由于缺乏信息如何通过角度service执行此操作,我才走这条路。理想情况下,服务会处理这种http请求。另请注意,在服务中使用$resource时,它会附带一些函数,其中一个函数为save()。但是,这对我来说也没有用。

articles.js控制器

app.controller('FormCtrl', function($scope, $http) {
$scope.addPost = function() {
$scope.article = {
  'article': {
    'title'  : $scope.article.title,
    'body'   : $scope.article.body
  }
};

// Why can't I use Article.save() method from $resource?
    $http({
        method: 'POST',
        url: 'http://localhost:3000/articles',
    data: $scope.article
    });
};

});

由于Rails是后端,因此向POST路径发送/articles请求会调用#create方法。对我来说,这是一个比我之前尝试过的更简单的解决方案。

要了解使用services$resource可让您访问save()功能。但是,我仍然没有在这种情况下揭开如何使用它的神秘面纱。我选择了$http,因为它的功能很明确。

肖恩希尔有一个建议,这是我今天第二次见到。对于解决这个问题的其他人来说,这可能会有所帮助。如果我遇到使用服务的解决方案,我会更新它。

谢谢大家的帮助。

答案 1 :(得分:2)

我使用Angular和Rails工作很多,我强烈建议使用AngularJS Rails资源。它使得使用Rails后端变得更容易。

https://github.com/FineLinePrototyping/angularjs-rails-resource

您需要在应用依赖项中指定此模块,然后您需要将工厂更改为:

app.factory('Article', function(railsResourceFactory) {
  return railsResourceFactory({url: '/articles', name: 'article');
});

基本上,根据您获得的错误,发生的情况是您的资源未创建正确的article参数。 AngularJS Rails Resource为您做到这一点,它还负责其他特定于Rails的行为。

此外,$scope.newPost不应为Article.save()。您应该使用新资源new Article()初始化它。

答案 2 :(得分:0)

在您的输入字段为空之前,模型中没有存储任何值,并且POST空文章对象。您可以通过创建客户端验证或在保存之前在所需字段上设置默认空字符串值来修复它。

首先,您应该在范围变量中创建新的Article对象,然后通过params传递newPost或直接访问$scope.newPost fn中的addArticle

app.controller('ArticlesCtrl', function($scope, Article) {
  $scope.articles   = Article.query();
  $scope.newPost    = new Article();

  $scope.addArticle = function(newPost) {
    if (newPost.title == null) {
      newPost.title = '';
    }
    // or if you have underscore or lodash:
    // lodash.defaults(newPost, { title: '' });
    Article.save(newPost);
  };
});

如果您想使用CRUD操作,您应该设置如下资源:

$resource('/articles/:id.json', { id: '@id' }, { 
  update: {
    method: 'PUT'
  }
});