简体   繁体   English

AngularJS + Rails发布请求

[英]AngularJS + Rails Post Request

I'm trying to learn to use AngularJS as the front-end framework in Rails applications. 我正在尝试学习将AngularJS用作Rails应用程序中的前端框架。 So far, I'm able to display a list of resources from the Rails app in view using Angular, and I can send a delete request with Angular. 到目前为止,我可以使用Angular在视图中显示Rails应用程序中的资源列表,并且可以使用Angular发送删除请求。 However, I'm having difficulty creating new resources. 但是,我在创建新资源方面遇到困难。 If someone could tell me what I might be doing wrong, that would be really appreciated. 如果有人可以告诉我我可能做错了什么,那将不胜感激。

edit I've made a bit of progresses. 编辑我取得了一些进展。 Looking at heroku logs, I realized I had made a silly mistake and forgot to account for the authenticity token. 在查看heroku日志时,我意识到自己犯了一个愚蠢的错误,并且忘记了对真实性令牌的解释。 Now I'm getting the error: ArgumentError (When assigning attributes, you must pass a hash as an argument.): 现在,我得到了错误:ArgumentError(分配属性时,必须将哈希作为参数传递。):

assets/javascript/angular_app.js 资产/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("/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 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

orders/index.html.erb orders / 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>

Try this instead 试试这个

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

and then something like this in Angular. 然后在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 = '';
        });
    }
 })

Your newOrder object isn't an instance of ngResource so when you are calling save on it, that doesn't work. 您的newOrder对象不是newOrder的实例,因此当您在其上调用save时,它将无法正常工作。 Assuming you are having some console errors in your browser as well along those lines. 假设您在浏览器中以及在这些方面都存在一些控制台错误。

You also need the update: patch custom method on ngResource because Rails looks for updates as patch and not put or else you will be asking that question after you figure out this one :). 您还需要ngResource上的update:patch自定义方法,因为Rails会将更新作为补丁而不是put进行查找,否则您会在发现一个问题后问这个问题:)。

Aha, I finally have it working. 啊哈,终于可以了。 I made a silly typo: 我做了一个愚蠢的错字:

In the create action of the orders controller 在订单控制器的创建动作中

   @order = Order.create(:order_params)

should be 应该

   @order = Order.create(order_params)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM