我正在尝试学习使用AngularJS作为Rails应用程序中的前端框架。到目前为止,我能够使用Angular在Rails应用程序中显示资源列表,我可以使用Angular发送删除请求。但是,我在创建新资源方面遇到了困难。如果有人能告诉我我可能做错了什么,那将非常感激。
修改的 我取得了一些进展。看着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("/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 :(得分: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的一个实例,因此当您调用save对它进行保存时,这并不起作用。假设您的浏览器中也出现了一些控制台错误。
您还需要更新:ngResource上的补丁自定义方法,因为Rails会将更新作为补丁进行查找而不是放入,否则您在找到这个问题后会问这个问题:)。
答案 1 :(得分:0)
在订单控制器的创建操作中
@order = Order.create(:order_params)
应该是
@order = Order.create(order_params)