私はユーザーがプレイリストに曲を追加できる音楽アプリを作成しようとしています。私は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"変数をどのように設定すればよいか、少し気をつけてもらえますか?
私のプロジェクトに他のコードが必要な場合は教えてください。私はそれを提供して喜んでします。