The two models involved here are the Item and Inventory models, having a "has_many :through => :categorizations" relationship to each other. Namely, each item has and belongs to inventory(s) and vise versa. The problem is that the "inventories" attribute is not saved to database when updating the item, while other non-nested attributes can be properly updated. Your help is much appreciated T.T
item.rb
class Item < ActiveRecord::Base
has_many :checkouts, :dependent => :destroy
has_many :categorizations
has_many :inventories, :through => :categorizations
accepts_nested_attributes_for :categorizations, :allow_destroy => true, :reject_if => :all_blank
accepts_nested_attributes_for :inventories
end
inventory.rb
class Inventory < ActiveRecord::Base
has_many :categorizations
has_many :items, :through => :categorizations
accepts_nested_attributes_for :categorizations, :allow_destroy => true, :reject_if => :all_blank
end
items_controller.rb
# PUT /items/1
# PUT /items/1.json
def update
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item, :notice => 'Item was successfully updated.' }
format.json { respond_with(@item) }
else
format.html { render action: 'edit' }
#format.json { render json: @item.errors, status: :unprocessable_entity }
respond_with(@item)
end
end
end
......
def item_params
params.require(:item).permit!
end
ItemsController.coffee (the angular controller for all templates)
controllers = angular.module('controllers')
controllers.controller("ItemsController", [ '$scope', '$routeParams', '$location','$resource','Flash','ngDialog'
($scope,$routeParams,$location,$resource,Flash,ngDialog)->
#Item querying
Item = $resource('/api/items/:itemId', { itemId: "@id", format: 'json' },
{
'get': { method: 'GET'},
'save': { method:'PUT'},
'create': { method:'POST'},
'update': { method:'PUT'},
'duplicate': { url: 'api/items/:itemId/duplicate', method:'PUT'},
'checkin': { url: '/api/items/:itemId/checkin', method:'PUT'}
'checkin': { url: '/api/items/:itemId/checkin', method:'GET'},
'checkout': { url: '/api/items/:itemId/checkout', method:'GET'},
'checkout': { url: '/api/items/:itemId/checkout', method:'POST'}
}
)
Item.query().$promise.then ((items) ->
$scope.items = items
), (errResponse) ->
#Inventory querying
Inventory = $resource('/api/inventories/:inventoryId', { inventoryId: "@id", format: 'json' },
{
'get': { method: 'GET'},
'save': {method:'PUT'},
'create': {method:'POST'}
}
)
Inventory.query().$promise.then ((inventories) ->
$scope.inventories = inventories
), (errResponse) ->
$scope.saveItem = ->
onError = (_httpResponse)-> flash.error = "Something went wrong"
if $scope.item.id
$scope.$apply ->
$scope.item.$update({itemId: $scope.item.id}
( ()->
console.log $scope.item.inventories
ngDialog.close()
$scope.openItemView($scope.item)
$scope.warningUpdateItem() ),
onError)
else
Item.create($scope.item,
( (newItem)->
ngDialog.close()
$scope.openItemView(newItem)
$scope.warningCreateItem() ),
onError
)
edit_item.html.erb
<div class="form-group" ng-class="{'has-warning has-feedback':errors.name}" ng-repeat="inventory in item.inventories">
<label for="inventories">
Inventory
</label>
<input type="text" name="inventories" class="form-control" ng-model='inventory.name' placeholder="Item inventories"></input>
</div>
Server Response when editing the inventories attributes of an item
Started PUT "/api/items/15?format=json" for ::1 at 2015-03-26 16:14:54 -0400
Processing by ItemsController#update as JSON
Parameters: {"id"=>"15", "name"=>"arashi", "quantity"=>1, "notes"=>"", "tags"=>"岚", "price"=>23, "purchase_date"=>nil, "needs_repair"=>false, "repair_notes"=>"", "is_disposed"=>false, "disposed_on"=>nil, "is_out"=>nil, "created_at"=>"2015-03-26T13:17:36.000Z", "updated_at"=>"2015-03-26T19:48:21.000Z", "warranty_expires_on"=>nil, "inventories"=>[{"id"=>1007, "name"=>"Groups", "created_at"=>"2015-03-26T13:17:36.000Z", "updated_at"=>"2015-03-26T13:17:36.000Z"}], "item"=>{"id"=>"15", "name"=>"arashi", "quantity"=>1, "notes"=>"", "tags"=>"岚", "price"=>23, "purchase_date"=>nil, "needs_repair"=>false, "repair_notes"=>"", "is_disposed"=>false, "disposed_on"=>nil, "is_out"=>nil, "created_at"=>"2015-03-26T13:17:36.000Z", "updated_at"=>"2015-03-26T19:48:21.000Z", "warranty_expires_on"=>nil}}
Can't verify CSRF token authenticity
Item Load (0.3ms) SELECT `items`.* FROM `items` WHERE `items`.`id` = 15 LIMIT 1
(0.1ms) BEGIN (0.1ms) COMMIT Completed 204 No Content in 17ms (ActiveRecord: 0.5ms)