使用Ajax导航嵌套表单

Chr*_*ris 5 ajax ruby-on-rails nested-forms ruby-on-rails-3

我有一个有趣的问题涉及我的Rails 3音乐应用程序中的对象创建步骤.

我有两个型号(不是实际型号;但为了简单起见):播放列表歌曲

播放列表有很多歌曲; 歌曲属于播放列表.

每个播放列表对象必须具有确切数量的歌曲.每首歌必须属于播放列表.

鉴于此,我想创建一个创建播放列表的过程,该过程还涉及同时创建所有必需的歌曲.

另一件事是,为了获取Song数据,用户输入一个查询(我不会在Song模型中保存),然后我从API收集数据.这是应该用于制作Song对象的数据.因此,我不能(不要想?)使用传统的form_for.

相反,我正在使用远程form_tag.此表单要求查询,然后使用Ajax请求获取数据,该数据被放入临时Song对象,然后使用Song视图在播放列表创建页面上内联显示.此表单将重复用于播放列表的所有必需的Song对象.

因此,想法是当用户输入所需数量的查询(即将所需数量的歌曲添加到播放列表中)时,他们会看到一个新按钮,使他们能够提交播放列表信息并继续进行.然后将使用通过Ajax作为子项创建的所有Song对象创建播放列表.

实际上,我无法找到一种优雅的方式来工作.虽然我通过Ajax创建了Song对象,但它们并没有保存在任何地方,并且他们不知道应该添加哪个播放列表(因为播放列表对象在数据库中也不存在.)因此,当我进入下一步时,我没有收到所有的宋数据.我研究了使用带有accepts_nested_attributes_for的嵌套表单,但是我无法找到一种方法将它用于我的设置(使用Ajax的非基于模型的表单.)

所以,我被困住了.如果有人可以提供帮助,我们将非常感激.

bio*_*net 1

我以前遇到过类似的问题。根据记录,我从未发现远程标签有用,也从未最终将它们用于如此复杂的事情。你是对的——带有accepts_nested_attributes_for的嵌套表单就是为这种事情而设计的,而且肯定有一种方法可以让它发挥作用。

您需要做的是,在 Ajax 查询之后,使用 JavaScript 动态生成嵌套的 Song 字段。例如,假设您有:

<form...>
  <input type="text" name="playlist[name]" />
  <div class="songs">
  </div>
</form>
Run Code Online (Sandbox Code Playgroud)

你会希望你的 Ajax 回调做类似的事情(我假设这里是 jQuery):

<script type="text/javascript">
  $(function() {
    var songs = $('form .songs') // Store a reference to the DOM song container
    // Insert Ajaxy goodness for song lookup here.
    // When it's finished, it should call add_song and pass in any data it needs
  })

  function add_song(song_name, artist_name, artist_id) {
    var num_songs = $(songs).size()
    $(songs).append('<p>'+song_name+' by '+artist_name+
      '<input type="hidden" name="playlist[songs_attributes]['+num_songs+'][name]" value="'+song_name+'" />' +
      '<input type="hidden" name="playlist[songs_attributes]['+num_songs+'][artist_id]" value="'+artist_id+'" /></p>')
  }
</script>
Run Code Online (Sandbox Code Playgroud)

那里发生了一些事情:

  1. 字段名称“playlist[songs_attributes]...”告诉 Rails 该字段属于嵌套属性
  2. “playlist[songs_attributes]...”之后的 num_songs 索引非常重要。相反,每首歌都必须是独一无二的,这一点非常重要。将其视为数组索引。因此,根据不断增加的歌曲列表的大小来确定它是完美的。(在我看来,这是动态创建嵌套表单字段中最棘手和最不明显的部分。)

我的代码可能并不完美,而且我确信我无论如何都没有得到正确的字段名称。但这应该是一个好的开始。此外,在应用程序的开发日志中查看提交的表单数据对于调试这些内容非常有帮助。