2016-02-13 72 views
1

我一直在爭取這一段時間,我無法弄清楚。我有一個使用設計的用戶模型。用戶可以上傳歌曲,並添加youtube視頻等。紅寶石軌道上。在不同的視圖中嵌套模型的形式

我試圖讓用戶添加/刪除歌曲和視頻從設計edit registrations視圖。

視頻上傳正常,但由於歌曲是播放列表的嵌套資源,屬於用戶,所以我認爲我會陷入混亂。

音樂上傳與其相應的頁面上有相同的表單,但不是從設計registration edit視圖中上傳。

路線:

devise_for :users, controllers: { registrations: "users/registrations", sessions: "users/sessions" } 

    resources :videos 

    resources :playlists do 
    resources :songs 
    end 

設計註冊控制器:

def edit 
    @song = Song.new 
    @video = Video.new 
    end 

表格中色器件編輯註冊:

<div id="user-music-box"> 
    <p class="p-details-title"> Upload Music </p> 
<%= simple_form_for [@user.playlist, @song] do |f| %> 
<%= f.file_field :audio %> 
<%= f.button :submit %> 
<% end %> 
</div> 

<div id="user-video-box"> 
    <p class="p-details-title"> Add videos </p> 
<%= simple_form_for @video do |f| %> 
<%= f.input :youtubeurl %> 
<%= f.button :submit %> 
<% end %> 
</div> 

正如我所說的,視頻(這是YouTube網址字符串)創建並保存沒有問題。歌曲完全一樣,基本上似乎只是更新用戶registration。歌曲信息顯示在服務器日誌中,但不存在playlist_id,並且不會保存任何內容。

歌曲控制器:

def new 
     if user_signed_in? 
     @song = Song.new 
     if current_user.playlist.songs.count >= 5 
     redirect_to user_path(current_user) 
     flash[:danger] = "You can only upload 5 songs." 
     end 
     else 
    redirect_to(root_url) 
    flash[:danger] = "You must sign in to upload songs" 
    end 
    end 

    def create 
    @song = current_user.playlist.songs.new song_params 
    @song.playlist_id = @playlist.id 
    if @song.save 
     respond_to do |format| 
      format.html {redirect_to user_path(current_user)} 
      format.js 
     end 
    else 
     render 'new' 
    end 
    end 

Playlist.rb

class Playlist < ActiveRecord::Base 
    belongs_to :user 
    has_many :songs, :dependent => :destroy 
    accepts_nested_attributes_for :songs 
end 

song.rb

class Song < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :playlist 
    has_attached_file :audio 
    validates_attachment_presence :audio 
    validates_attachment_content_type :audio, :content_type => ['audio/mp3','audio/mpeg'] 
end 

回答

1

除非你傳遞songs/playlists通過accepts_nested_attributes_for你不應該使用registrations#edit。我會詳細的兩種方式來實現你想要的下面:


嵌套屬性

#app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :videos 

    has_many :playlists 
    has_many :songs, through: :playlists 

    accepts_nested_attributes_for :videos 
end 

#app/models/playlist.rb 
class PlayList < ActiveRecord::Base 
    belongs_to :user 
    has_and_belongs_to_many :songs 
end 

#app/models/song.rb 
class Song < ActiveRecord::Base 
    has_and_belongs_to_many :playlists 
end 

這樣做的重要性,要正確地使用它,你能夠編輯@user直接對象,通過嵌套的屬性通過fields_for幫手:

#config/routes.rb 
devise_for :users, controllers: { registrations: "users/registrations", sessions: "users/sessions" } 

#app/controllers/users/registrations_controller.rb 
class Users::RegistrationsController < ApplicationController 
    before_action :authenticate_user!, only: [:edit, :update] 

    def edit 
    @user = current_user 
    @user.playlists.build.build_song 
    @user.videos.build 
    end 

    def update 
    @user = current_user.update user_params 
    end 

    private 

    def user_params 
    params.require(:user).permit(:user, :attributes, videos_attributes: [:youtubeurl], playlists_attributes: [song_ids: [], song_attributes: [:title, :artist, :etc]]) 
    end 
end 

這將允許你使用方法:

#app/views/users/registrations/edit.html.erb 
<%= form_for @user do |f| %> 
    <%= f.fields_for :videos do |v| %> 
    <%= v.text_field :youtubeurl %> 
    <% end %> 
    <%= f.fields_for :playlists do |p| %> 
    <%= p.collection_select :song_ids, Song.all, :id, :name %> 
    <%= p.fields_for :song do |s| %> 
     <%= f.text_field :title %> 
    <% end %> 
    <% end %> 
    <%= f.submit %> 
<% end %> 

這會給你一個形式,從中你將能夠爲@user創建videosplaylistssongs


獨立

另一種選擇是分別創建對象。

沒有什麼技術原因比nested attributes更喜歡這種方式;你會這樣做,以確保你有正確的順序路線等。

作爲一個說明,你需要記住,路線!=模型結構。你可以有你想要的任何路由,只要他們定義你的模型的良好格局:

# config/routes.rb 
authenticated :user do #-> user has to be logged in 
    resources :videos, :playlists, :songs #-> url.com/videos/new 
end 

# app/controllers/videos_controller.rb 
class VideosController < ApplicationController 
    def new 
    @video = current_user.videos.new 
    end 

    def create 
    @video = current_user.videos.new video_params 
    @video.save 
    end 

    private 

    def video_params 
    params.require(:video).permit(:youtubeurl) 
    end 
end 

# app/views/videos/new.html.erb 
<%= form_for @video do |f| %> 
    <%= f.text_field :youtubeurl %> 
    <%= f.submit %> 
<% end %> 

以上將需要VideosController的重實現PlaylistsSongs

+0

感謝您對這樣的深度回答。我嘗試過各種形式,並遇到很多錯誤。目前我已經用歌曲清除了播放列表和嵌套資源。用戶現在擁有視頻和歌曲。我可以從註冊編輯頁面成功創建新視頻,因爲表單會從視頻控制器中觸發。當我嘗試提交上傳歌曲表單時,歌曲控制器不會被解僱,只是註冊控制器(我不明白爲什麼)。對於我的設置,我不認爲我真的需要嵌套的資源,只是在其他控制器中使用表單的能力。 –

+0

最後我放棄了。我無法以這種方式獲得歌曲。視頻很好,我無法找到兩個模型之間的任何區別,所以我不明白爲什麼它不起作用。對於歌曲,我剛剛在註冊編輯視圖中呈現了部分表單,並且按照需要運行。 –

+1

NO。你絕不能阻止它。你甚至沒有嘗試過。你現在在嗎?讓我們跳進聊天並完成它 –