2015-11-18 268 views
0

我正在尝试学习如何在Rails应用程序中使用AngularJS作为前端框架。到目前为止,我可以使用Angular在视图中显示Rails应用程序中的资源列表,并且可以使用Angular发送删除请求。但是,我很难创建新资源。如果有人能告诉我我可能做错了什么,那将会非常感激。AngularJS + Rails发布请求

编辑 我已经取得了一些进展。看着Heroku的日志,我意识到我犯了一个愚蠢的错误,忘记了解释真实性标记。现在我得到的错误:引发ArgumentError(在分配属性,你必须通过一个哈希作为参数。):

资产/ JavaScript的/ angular_app.js

var app = angular.module('shop', ['ngResource']); 

app.factory('models', ['$resource', function($resource){ 
    var orders_model = $resource("/orders/:id.json", {id: "@id"}); 
    var products_model = $resource("/products/:id.json", {id: "@id"}); 
    var users_model = $resource("https://stackoverflow.com/users/:id.json", {id: "@id"}); 
    var x = { 
     orders: orders_model, 
     products: products_model, 
     users: users_model 
    }; 
    return x; 
}]); 

app.controller('OrdersCtrl', ['$scope', 'models', function($scope, models){ 
    $scope.orders = models.orders.query(); 
    $scope.products = models.products.query(); 
    $scope.users = models.users.query(); 
    $scope.addOrder = function(){ 
     order = models.orders.save($scope.newOrder, function(){ 
      recent_order = models.orders.get({id: order.id}); 
      $scope.orders.push(recent_order); 
      $scope.newOrder = ''; 
     }); 
    } 
    $scope.deleteOrder = function(order){ 
     models.orders.delete(order); 
     $scope.orders.splice($scope.orders.indexOf(order), 1); 
    } 
}]); 

orders_controller.rb

class OrdersController < ApplicationController   
    protect_from_forgery 
    skip_before_action :verify_authenticity_token, if: :json_request?ion 
    respond_to :json, :html 

    def index 
     @orders = Order.all.to_json(:include => [{:product => {:only => :name}}, 
               {:user => {:only => :email}}]) 
     respond_with @orders 
    end 

    def show 
     @order = Order.find(params[:id]).to_json(:include => [{:product => {:only => :name}}, 
                   {:user => {:only => :email}}]) 
     respond_with @order 
    end 

    def new 
    end 

    def create 
     @order = Order.create(:order_params) 
     @order.product = Product.find(params[:product_id]) 
     @order.user = User.find(params[:user_id]) 

     OrderMailer.order_confirmation(@order.product, @order.user.email, @order.user.first_name) 

     respond_with @order 
    end 

    def destroy 
     respond_with Order.destroy(params[:id]) 
    end 

    protected 

    def json_request? 
     request.format.json? 
    end 

    private 

    def order_params 
     params.require(:order).permit(:product_id, :user_id, :total) 
    end 
end 

订单/ index.html.erb

<div ng-controller="OrdersCtrl"> 
    <table class="table table-hover"> 
     <thead> 
      <td>Order ID</td> 
      <td>Total</td> 
      <td>Product</td> 
      <td></td> 
     </thead> 
     <tr> 
      <form ng-submit="addOrder()"> 
       <td> 
        <span class="form-control" disabled> 
         <%= Order.last.id + 1 %> 
        </span> 
       </td> 
       <td> 
        <input type="number" step="0.01" class="form-control" ng-model="newOrder.total"> 
       </td> 
       <td> 
        <select ng-model="newOrder.product_id" class="form-control"> 
         <option value="" disabled selected>Select a product</option> 
         <option ng-repeat="product in products" value="{{product.id}}">{{product.name}}</option> 
        </select> 
       </td> 
       <td> 
        <select ng-model="newOrder.user_id" class="form-control"> 
         <option value="" disabled selected>Select a user</option> 
         <option ng-repeat="user in users" value="{{user.id}}">{{user.id}}</option> 
        </select> 
       </td> 
       <td> 
        <input type="submit" value="+" class="btn btn-success"> 
       </td> 
      </form> 
     </tr> 
     <tr ng-repeat="order in orders | orderBy: '-id':reverse"> 
      <td> 
       {{order.id}} 
      </td> 
      <td> 
       <strong>{{order.total | currency}}</strong> 
      </td> 
      <td> 
       {{order.product.name}} 
      </td> 
      <td> 
       {{order.user.email}} 
      </td> 
      <td> 
       <button ng-click="deleteOrder(order)" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button> 
      </td> 
     </tr> 
    </table> 
</div> 

回答

0

试试这个

app.factory('Order', ['$resource', function($resource) { 
    return $resource('/api/orders/:id.json', null, 
    { 
     'update': { method:'PATCH' } 
    }); 
}]); 

然后在Angular中这样做。

app.controller('OrdersCtrl', ['$scope', 'models' 'Order', function($scope, models, Order){ 
... 

    $scope.addOrder = function(){ 
     var order = new Order($scope.newOrder); 
     Order.save(order, function(res){ 
      $scope.orders.push(res); 
      $scope.newOrder = ''; 
     }); 
    } 
}) 

newOrder对象不是那么当你调用保存就可以ngResource的实例,这是行不通的。假设您的浏览器中出现了一些控制台错误,并且还有这些行。

您还需要在ngResource上进行更新:patch自定义方法,因为Rails会将修补程序查找为修补程序而不是放置,否则在找出这个之后您会问这个问题:)。

+0

感谢您的提示,是有道理的。我没有收到错误,POST http:// localhost:3000/api/orders.json 404(Not Found) 而我得到500错误之前。 –

+0

我设法通过查看heroku日志取得一些进展。我编辑了主帖。 –

0

啊哈,我终于有了它的工作。我犯了一个愚蠢的错字:

在单控制器

@order = Order.create(:order_params) 

的创建动作要

@order = Order.create(order_params)