18138


1つの Shop のなかに複数の Shelf がありその中に Item が格納されているケースを想定しています。  
ngResourceを使ってjsonでレンダリングされた "/api/shops/:shop_id/shelfs/:shelf_id/items/:id"
を呼び出して、データベースに item を追加しようとしています。

《controller》shop_edit.coffee

[code]

    angular.module("myApp").controller "shopEdit", ($scope, Shop, Shelf, Item) ->
    
      $scope.init = ->
        # Rails側でパラメータを取得してng-initからshop_idを設定
        shop_id = $scope.shop_id
        # Shopを取得
        Article.get(id: shop_id).$promise.then (shop) ->
          $scope.shop = shop
        return
    
      $scope.saveItem = (shop, shelf) ->
        # 保存
        $scope.newItem = { name: shelf.item.name, shop_id: shop.id, shelf_id: shelf.id }
        Item.save($scope.newItem)
        $scope.newItem = newItem
        return
    
[/code]

《view》edit.html.slim

[code]

    (一部抜粋)
    .item
      input name="name" ng-model="shelf.item.name" ng-blur="saveItem(shop, shelf)"
    
[/code]

《service》shop.coffee

[code]

    angular.module('myApp').factory 'Shop', ($resource) ->
      $resource('/api/shops/:id', { id: @id }, { update: { method: 'PUT' }})
    
[/code]

《service》item.coffee

[code]

    angular.module('myApp').factory 'Item', ($resource) ->
      $resource('/api/shops/:shop_id/shelfs/:shelf_id/items/:id',
        { shop_id: '13495' },
        { shelf_id: '93' },
        { update: { method: 'PUT' }})
    
[/code]

このとき、動的な値 shop_id と shelf_id をcontorollerから受け取れずに困っています。  
$scope.newItem = { ... } の中で shop_id と item_id を指定し、Item.save($scope.newItem)
で service 側に渡しているのですが正しく受け取れないようで困ってます（:shop_id, :shelf_id が空欄になり保存に失敗しています）。

また、なぜか、以下のように :shelf_id を :shop_id に置き換えないと正しく保存されません...

[code]

    $resource('/api/shops/:shop_id/shelfs/:shop_id/items/:id',
      { shop_id: '13495' },
      { update: { method: 'PUT' }})
    
[/code]

原因が検討もつかず困っています... どうかよろしくお願いいたします。


CC BY-SA 3.0
2015-10-27T11:13:55.897
18133
2015-10-27T13:35:35.047
10441
question
javascript angularjs coffeescript
ngResourceでネストされたアイテムの追加ができず困っています


`item.coffee`内での`$resource`の使い方が間違っています。  
第一引数はURLテンプレート、第二引数はデフォルトパラメータ、第三引数はアクションです。

[code]

    angular.module('myApp')
    .factory('Item', function($resource) {
      return $resource('', {}, {
        update: {
          url: '/api/shops/:shop_id/shelfs/:shelf_id/items/:id',
          method: 'PUT',
          params: {id: '@id', shop_id: '@shop_id', shelf_id: '@shelf_id'}
        }
      });
    })
    
[/code]

`update`アクションを作るのでしたらこんな感じでしょうか。  
これでコントローラから`Item.update($scope.newItem)`すればOKです。

POST系のメソッドでデータをURLテンプレートに展開したい場合、上のように`@`付きの書式で`params`を指定する必要があります。

公式ドキュメントをよくお読みください。  
<https://docs.angularjs.org/api/ngResource/service/$resource>


CC BY-SA 3.0
2015-10-27T13:35:35.047
18138
2015-10-27T13:35:35.047
8532
18133
answer