如何将现有歌曲添加到音乐库Rails 4

时间:2016-07-17 20:47:59

标签: ruby-on-rails database

我要做的是添加艺术家已经上传到用户库的歌曲(我已经设置了我的应用,以便艺术家可以上传歌曲)。此外,我已经设置了我的代码,以便在用户注册后创建一个空的用户库(使用after_create Active Record Callback)。

为了更清楚,我希望用户能够将他们在网站中看到的歌曲添加到他们的库中。

然而,这正在逃避我。我熟悉CRUD,并且知道如何创建一个库并添加现有歌曲,但是我不太确定如何通过点击“添加歌曲到”的按钮/链接将歌曲添加到用户库库“将在一首歌旁边,并将其添加到用户现有的空库中。

我现有的代码如下。

User.rb:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :meta, polymorphic: true

  before_create :create_empty_profile

  after_create :create_empty_library #may not be the best way to do it ¯\_(ツ)_/¯

  acts_as_messageable

  has_many :playlists

  has_many :user_friendships, dependent: :destroy
  has_many :friends, -> { where(user_friendships: { state: 'accepted'}) }, through: :user_friendships
  has_many :pending_user_friendships, -> { where ({ state: 'pending' }) }, class_name: 'UserFriendship', foreign_key: :user_id
  has_many :pending_friends, through: :pending_user_friendships, source: :friend

  has_many :chat_rooms, dependent: :destroy
  has_many :chat_messages, dependent: :destroy

  has_many :votes, dependent: :destroy

  mount_uploader :profile_pic, ProfilePicUploader

    def mailboxer_name
      self.name
    end

    def mailboxer_email(object)
      self.email
    end

  def admin?
    role == 'admin'
  end

  def moderator?
    role == 'moderator'
  end

  def create_empty_profile
    if is_artist?
      profile = ArtistProfile.new
    else
      profile = UserProfile.new
    end
    profile.save(validate: false)
    self.meta_id = profile.id
    self.meta_type = profile.class.name
  end

  def create_empty_library
    library = Library.new
    library.user_id = self.id
    library.save(validate: false)
  end

end

Library.rb:

class Library < ActiveRecord::Base
  belongs_to :user

  has_many :library_songs
  has_many :songs, through: :library_songs

  has_many :library_albums
  has_many :albums, through: :library_albums
end

library_song.rb

class LibrarySong < ActiveRecord::Base
  belongs_to :library
  belongs_to :song
end

library_album.rb

class LibraryAlbum < ActiveRecord::Base
  belongs_to :library
  belongs_to :album
end

libraries_controller.rb

class LibrariesController < ApplicationController
  def index
    @libraries = Library.all
  end

  def show
    @library = Library.find(params[:id])
  end
end

我可以使用下面的表单/控制器创建播放列表并添加歌曲。

播放列表/ new.html.erb:

<h1>New Playlist</h1>

<%= form_for(@playlist) do |f| %>
  <%= f.text_field :name %>

  <% Song.all.each do |song| -%>
    <div>
      <%= check_box_tag :song_ids, song.id, false, :name => 'playlist[song_ids][]', id: "song-#{song.id}" %>
      <%= song.name %>
    </div>
  <% end %>

  <%= f.submit %>
<% end %>

playlists_controller.rb:

class PlaylistsController < ApplicationController
  def index
    @playlists = Playlist.all
  end

  def show
    @playlist = Playlist.find(params[:id])
  end

  def new
    @playlist = Playlist.new
  end

  def create
    @playlist = Playlist.create(playlist_params)
    redirect_to @playlist
  end

  private

  def playlist_params
    params.require(:playlist).permit(:name, song_ids: [])
  end
end

然而,主要问题是在上面的表格中,播放列表与现有歌曲一起创建。在这种情况下,我需要将现有歌曲添加到空的现有库中。

任何想法,伙计们?这将非常有帮助。我很乐意上传所需的任何代码。

1 个答案:

答案 0 :(得分:0)

在我看来,您实际上并没有在用户模型中设置has_many:libraries。从您的图书馆模型来看,我认为这是您的意图。你应该真的只是创造新的&#39;保存用户模型之前的模型。你可以使用与此类似的东西,并在一个动作中完成所有操作。

class User < ActiveRecord::Base
  def self.build_full_user(params, songs)
    # Assign all normal attributes here
    new_user = User.new
    new_user.name = params[:name]

    # If you want to assign new songs, just make a new Library model and associate them. 
    new_library = Library.new

    # Build the song models if you haven't found/created or passed them in already.
    new_songs = Songs.build_songs_from_list(songs) 
    new_library.songs << new_songs

    new_user.libraries << new_library

    # You can do the save check here or up one level if you'd like. 
    return new_user
  end
end