无法正确保存具有file_field的嵌套表单

时间:2014-04-24 09:16:05

标签: audio ruby-on-rails-4

使用paperclip和ruby-mp3info上传和阅读文件信息,我有一个表单,用于创建播放列表及其子项,轨道:

 <%= form_for(@playlist) do |f| %>
  <% if @playlist.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@playlist.errors.count, "error") %> prohibited this playlist from being saved:</h2>

      <ul>
      <% @playlist.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label "Name: " %>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label " Image: " %>
    <%= f.file_field :photo %>
  </div>
  <br>
  <div class="field">
  <br>
    <%= f.text_area :description, :size => "80x3"%>
  </div>
  <br>
  <div class="field">
    <%= f.fields_for :tracks, Track.new do |ff| %>
      <%= ff.file_field :audio %>
    <% end %>
  </div>
  <% if !@playlist.tracks.blank? %>
  <table id="tracks" class="table">
      <thead>
        <tr>
          <th>Track</th>
          <th>Album</th>
          <th>Artist</th>
          <th>Label</th>
        </tr>
      </thead>
    <tbody>
    <%= f.fields_for :tracks do |ff| %>
      <%= render "track_fields", :f => ff %>
    <% end %>
    </tbody>
  </table>
  <% end %>
  <div class="actions">
    <%= f.submit "Save" %>
  </div>    

<% end %>

上传文件的问题是,在我点击“保存”按钮之前,我一直没有这个问题。所以我从我的控制器中读取了信息。在我的播放列表控制器的更新方法中,我尝试通过以下代码创建一个新轨道:

def update

    track = @playlist.tracks.new()
    Mp3Info.open(playlist_params["tracks_attributes"]["0"]["audio"].path.to_s) do |info|

      track.audio_file_name = info.tag.title
      track.artist = info.tag.artist
      track.album  = info.tag.album
      # tracknum = info.tag.tracknum.to_s
    end


    respond_to do |format|
      if @playlist.update(playlist_params)
        format.html { redirect_to @playlist, notice: 'Playlist was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

问题是我的update方法中的代码会在我只想要一个时创建两个轨道实例。如何仅在我的控制器中创建我正在创建的实例,并忽略从表单中创建的新轨道?

有没有其他方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

您在tracks表格中获得了两条记录,因为您正在使用form(使用track_attributes)创建一条记录,而您正在update动作中创建其他记录。

如果您只需要更新要保存的曲目的少数属性,请在params[:playlist][:tracks_attributes]的曲目中进行更新。

更改update操作,如下所示:

  def update

    Mp3Info.open(playlist_params["tracks_attributes"]["0"]["audio"].path.to_s) do |info|

      params[:playlist][:tracks_attributes]["0"][:audio_file_name] = info.tag.title
      params[:playlist][:tracks_attributes]["0"][:artist] = info.tag.artist
      params[:playlist][:tracks_attributes]["0"][:album]  = info.tag.album
      # tracknum = info.tag.tracknum.to_s
    end


    respond_to do |format|
      if @playlist.update(playlist_params)
        format.html { redirect_to @playlist, notice: 'Playlist was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

这将为Track表格中的Playlist仅创建一个关联的tracks记录。