0

私はユーザーがプレイリストに曲を追加できる音楽アプリを作成しようとしています。私はhas_manyアソシエーションを作成して、 "playlist_songs"が "songs"の代わりにプレイリストに追加されるようにしましたhas_many-Rails AngularJS Restangular 'POST'

あなたに良いアイデアを与えるための関連コードは以下のとおりです。

playlist_song.rb

class PlaylistSong < ActiveRecord::Base 
    belongs_to :playlist 
    belongs_to :song 
end 

song.rb

class Song < ActiveRecord::Base 
    belongs_to :album 
    has_many :playlist_songs 
    has_many :playlists, through: :playlist_songs 
end 

playlist.rb

class Playlist < ActiveRecord::Base 
    belongs_to :user 
    has_many :playlist_songs 
    has_many :songs, through: :playlist_songs 
end 

Song.attribute_names

["id", "url", "name", "created_at", "updated_at", "album_id", "song_title"] 
私がやろうとしています何

PlaylistSong.attribute_names

["id", "playlist_id", "song_id", "created_at", "updated_at"] 

特定のプレイリストにplaylist_songを追加することです。私はこれを行う最良の方法は、単にsong_id属性とplaylist_id属性しか持たないplaylist_songを作成することだと仮定しました。これは、私が必要とする曲URLと、その曲が属するplaylist_idを参照します。

私は次のように表示されたURL、http://localhost:3000/api/user_profiles/1/playlists/8/song_referencesにplaylist_songを保存したい:

[ 
    { 
    "id": 14, 
    "playlist_id": 8, 
    "song_id": 2, 
    "created_at": "2016-09-25T15:43:36.459Z", 
    "updated_at": "2016-09-25T15:43:36.459Z" 
    }, 
    { 
    "id": 15, 
    "playlist_id": 8, 
    "song_id": 3, 
    "created_at": "2016-09-25T15:43:36.460Z", 
    "updated_at": "2016-09-25T15:43:36.460Z" 
    } 
] 

特定のプレイリストとの関係で実際の曲の属性が表示されたURL、http://localhost:3000/api/user_profiles/1/playlists/8/playlist_songsから著しく異なっています:

namespace :api, defaults: { format: :json } do 
    # resources :newsfeed_item 
    resources :chat_rooms do 
     resources :chat_messages 
    end 
    resources :playlists do 
     resources :playlist_songs 
    end 
    resources :songs 
    resources :venue_requests 
    resources :user_profiles do 
     resources :libraries 
     resources :playlists do 
     resources :playlist_songs 
     resources :song_references 
     end 
    end 
    resources :artist_profiles do 
     resources :albums do 
     resources :album_songs 
     end 
    end 
    end 

[ 
    { 
    "id": 3, 
    "url": "https://www.song3url.mp3", 
    "name": "05 Smoke Signal (Original Mix).mp3", 
    "created_at": "2016-09-24T02:33:46.648Z", 
    "updated_at": "2016-09-29T03:44:35.464Z", 
    "album_id": 1, 
    "song_title": null 
    }, 
    { 
    "id": 2, 
    "url": "https://www.song2url.mp3", 
    "name": "07 The Son Of Flynn (Remixed by Moby).mp3", 
    "created_at": "2016-09-24T02:25:52.373Z", 
    "updated_at": "2016-09-24T02:25:52.373Z", 
    "album_id": 1, 
    "song_title": null 
    } 
] 

あなたは以下の私のroutes.rbをファイルの特定のAPI部分を見ることができますここで

はplaylist_songsを表示しているsong_references_controller.rbファイルです:

class Api::SongReferencesController < ApplicationController 
    def index 
    @playlist = Playlist.find(params[:playlist_id]) 
    @playlist_songs = PlaylistSong.where(playlist_id: params[:playlist_id]) 
    render json: @playlist_songs, status: :ok 
    end 

    def new 
    @playlist_song = PlaylistSong.new 
    end 

    def create 
    @playlist_song = PlaylistSong.new(playlist_song_params) 

    if @playlist_song.save 
     render json: @playlist_song, status: :created 
    else 
     render json: @playlist_song.errors, status: :unprocessable_entity 
    end 
    end 

    def playlist_song_params 
    params.fetch(:song, {}).permit(:song_id, :playlist_id) 
    end 
end 

そして、ここでは、私は、個々のプレイリストや曲のほか、$ scope.saveSong機能を表示しているPlaylistCtrl.jsファイルですプレイリストにplaylist_songsを保存するために使用しています:

(function(){ 
    function PlaylistCtrl($scope, $resource, $interval, Restangular, angularSoundManager) { 
    $scope.addToPlaylistVisible = false; 
    $scope.selectedPlaylist = Restangular.one('api/user_profiles/1/playlists', 8).all('song_references'); 
    $scope.allPlaylists = Restangular.all('api/playlists'); 

    $interval(function(){ 
     $scope.allPlaylists.getList().then(function(playlists) { 
     $scope.playlists = playlists; 
     }); 

     console.log("PLAYLISTS GRABBED"); 
    }, 1000); 

    $scope.basePlaylist = Restangular.one('api/playlists', 8).all('playlist_songs'); 
    $scope.playlistId = '8'; 

    $interval(function(){ 
     $scope.basePlaylist.getList().then(function(songs) { 
     $scope.songs = songs; 
     }); 

     console.log("Playlist Songs GRABBED"); 
    }, 1000); 

    $scope.setPlaylistAttributes = function(playlistId) { 
     $scope.basePlaylist = Restangular.one('api/playlists', playlistId).all('playlist_songs'); 
     $scope.playlistId = playlistId; 
     console.log("CURRENT PLAYLIST ID " + $scope.playlistId) 
    } 

    $scope.setSong = function(songId) { 
     $scope.songId = songId; 
     $scope.addToPlaylistVisible = true; 
     console.log("CURRENT SONG ID " + $scope.songId) 
    } 

    $interval(function(){ 
     $scope.selectedPlaylist.getList().then(function(playlistSongs) { 
     $scope.playlistSongs = playlistSongs; 
     }); 
     console.log("Working"); 
    }, 1000); 


    // CREATE PLAYLIST SONG (song_reference instance) - PLAYLIST ID, SONG ID (NOT SONG, BUT PLAYLIST SONG) 
    $scope.saveSong = function(selectedPlaylistId) { 
     $scope.selectedPlaylist = Restangular.one('api/user_profiles/1/playlists', selectedPlaylistId).all('song_references'); 
     $scope.selectedPlaylistId = selectedPlaylistId; 
     var newSong = { 
      "playlist_id": $scope.selectedPlaylistId, 
      "song_id": $scope.songId, 
     }; 
     $scope.selectedPlaylist.post(newSong).then(function(newSong){ 
     $scope.playlistSongs.push(newSong); 
     console.log(newSong); 
     }) 
    }; 

    $scope.hidePlaylists = function() { 
     $scope.addToPlaylistVisible = false; 
    } 

    } 
    angular 
     .module('PlaylistCtrl', ['angularSoundManager']) 
     .controller('PlaylistCtrl', ['$scope', '$resource', '$interval', 'Restangular', PlaylistCtrl]); 
})(); 

プレイリスト/ index.html.erb:

<h1>All Playlists</h1> 

<div ng-controller="PlaylistCtrl"> 
    <div> 
    <ul ng-repeat="playlist in playlists"> 
     <li> 
     <a style="cursor:pointer;" ng-click="setPlaylistAttributes(playlist.id);">{{ playlist.name }}</a> 
     </li> 
    </ul> 
    </div> 
    <%= link_to "New playlist", new_user_profile_playlist_path, data: { push: true } %> 
    <br/> 
    <br/> 
    <h3>Selected Playlist</h3> 
    <div> 
    <ul> 
     <li ng-repeat="song in songs"> 
     <a style="cursor:pointer;" music-player="play" add-song="song">{{ song.name }}</a> 
     <button ng-click="setSong(song.id);">ADD TO PLAYLIST</button> 
     </li> 
    </ul> 
    <button play-all="songs" data-play="false">Add all</button> 
    <div ng-if="addToPlaylistVisible"> 
     <a style="cursor:pointer;" ng-click="hidePlaylists();"><img src="/assets/HUD_icons/x.png"/></a> 
     <ul ng-repeat="playlist in playlists"> 
     <li> 
      <a style="cursor:pointer;" ng-click="saveSong(playlist.id);">{{ playlist.name }}</a> 
     </li> 
     </ul> 
    </div> 
    </div> 
</div> 

しかし、追加する正しいソングを選択し、追加するソングのプレイリストを選択して、そのプレイリストを保存すると、プレイリストのソングと一緒にアトリビュートは保存されません。

レールコンソールで見たとき、私はこのようになりますオブジェクトを取得:

=> #<PlaylistSong:0x007f9397d3c700 
id: 48, 
playlist_id: nil, 
song_id: nil, 
created_at: Wed, 12 Oct 2016 00:50:47 UTC +00:00, 
updated_at: Wed, 12 Oct 2016 00:50:47 UTC +00:00> 

をしかし、私は、サーバーのログでこれを参照してください。

Started POST "/api/user_profiles/1/playlists/8/song_references" for ::1 at 2016-10-11 20:50:47 -0400 
Processing by Api::SongReferencesController#create as JSON 
    Parameters: {"playlist_id"=>"8", "song_id"=>4, "user_profile_id"=>"1", "song_reference"=>{"playlist_id"=>"8", "song_id"=>4}} 
    (0.1ms) begin transaction 
    SQL (1.1ms) INSERT INTO "playlist_songs" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2016-10-12 00:50:47.752976"], ["updated_at", "2016-10-12 00:50:47.752976"]] 
    (8.2ms) commit transaction 
Completed 201 Created in 19ms (Views: 0.5ms | ActiveRecord: 9.5ms) 

私はplaylist_song_paramsを変更した場合song_references_controller.rbファイルを読み込みます。

def playlist_song_params 
    params.require(:playlist_song).permit(:song_id, :playlist_id) 
    end 

私は400のBAD REQUEST ERRORを取得しました。サーバログでこれを参照してください。

Started POST "/api/user_profiles/1/playlists/8/song_references" for ::1 at 2016-10-11 20:50:47 -0400 
Processing by Api::SongReferencesController#create as JSON 
    Parameters: {"playlist_id"=>"8", "song_id"=>4, "user_profile_id"=>"1", "song_reference"=>{"playlist_id"=>"8", "song_id"=>4}} 
    (0.1ms) begin transaction 
    SQL (1.1ms) INSERT INTO "playlist_songs" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2016-10-12 00:50:47.752976"], ["updated_at", "2016-10-12 00:50:47.752976"]] 
    (8.2ms) commit transaction 
Completed 201 Created in 19ms (Views: 0.5ms | ActiveRecord: 9.5ms) 

アムI完全にオフベース私は「playlist_songsを」節約について行くべきであるかのように?

もしそうなら、私は自分のstrong_paramsをどのように設定するか、 "$ scope.saveSong"関数内で "newSong"変数をどのように設定すればよいか、少し気をつけてもらえますか?

私のプロジェクトに他のコードが必要な場合は教えてください。私はそれを提供して喜んでします。

答えて

0

回答が見つかりました。

def playlist_song_params 
    params.permit(:playlist_id, :song_id) 
end 

私は、これは働いていた理由は分からないので、誰もがこの上でいくつかの光を当てるしたい場合、それは非常に高く評価されるだろう:私はplaylist_songは以下にplaylist_song_paramsを変更して保存する属性を取得することができました。