0

我有一个深层嵌套的资源。目前一切正常,除了当我创建一首歌曲时。由于某种原因,它不会将 ARTIST_ID 存储在数据库中(显示为 NIL)。有人可以帮助我吗,我是新手。

第一个嵌套将 ARTIST_ID 存储在 ALBUMS 表中......

路线.RB

resources :artists do
  resources :albums do
    resources :songs
  end
end

SONGS_CONTROLLER

class SongsController < ApplicationController

  respond_to :html, :js

  def index
    @artist = Artist.find(params[:artist_id])
    @album = Album.find(params[:album_id])
    @songs = @album.songs.all
  end

  def create
    @artist = Artist.find(params[:artist_id])
    @album = Album.find(params[:album_id])
    @song = @album.songs.create(params[:song])
      if @song.save
        redirect_to artist_album_songs_url
        flash[:success] = "Song Created."
      else
        render 'new'
      end
  end

  def new
    @artist = Artist.find(params[:artist_id])
    @album = Album.find(params[:album_id])
    @song = Song.new
  end

end

楷模

class Artist < ActiveRecord::Base
  attr_accessible :name

  has_many :albums
  has_many :songs

end

class Album < ActiveRecord::Base
  attr_accessible :name, :artist_id

  belongs_to :artist
  has_many :songs

end

class Song < ActiveRecord::Base
  attr_accessible :name, :album_id, :artist_id

  belongs_to :albums

end

查看(为歌曲创建)

<div class="container-fluid">
  <div class="row-fluid">

    <%= form_for ([@artist,@album, @song]), :html => { :multipart => true } do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

      <%= f.text_field :name, placeholder: "name", :class => "input-xlarge"%>

      <%= f.submit "Create Song", class: "btn btn-primary"%>

    <% end %>

  </div>

</div>
4

1 回答 1

1

看起来您没有在任何地方设置歌曲的artist_id。不过,您做得对 - 使用专辑 ID 和艺术家 ID,您必须选择其中一个作为父级。就好像您在歌曲中缓存了 artist_id。

我想我会按照您的方式保留它们,但将其添加到模型中。

class Song < ActiveRecord::Base

  before_save :ensure_artist_id


  def ensure_artist_id
    self.artist_id = self.album.artist_id
  end

end

另一个选项是在控制器中显式设置它

  def create
    @artist = Artist.find(params[:artist_id])
    @album = Album.find(params[:album_id])
    @song = @album.songs.create(params[:song].merge(:artist_id => @artist.id)
      if @song.save
        redirect_to artist_album_songs_url
        flash[:success] = "Song Created."
      else
        render 'new'
      end
  end

但这感觉不那么干净,可能会在其他控制器方法中重复。将它放在模型中会更好。

于 2013-05-29T20:14:57.117 回答