Rails - 在new / create动作中链接两个模型的属性

时间:2014-08-27 02:45:24

标签: ruby-on-rails forms rails-activerecord

这是我的第一个应用程序,我仍然对如何完成我想要完成的工作感到困惑。总之,我想创建相册,每个都有自己的跟踪列表。所以基本上我有一个专辑模型和一个跟踪列表模型及其关联如下:

# album.rb
  has_one :tracklist

# tracklist
  belongs_to :album

这将是他们的属性

create_table "albums", force: true do |t|
  t.string   "title"
  t.string   "artist"
  t.datetime "release_date"
  t.string   "label"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "tracklists", force: true do |t|
  t.string   "track_name"
  t.time     "duration"
  t.datetime "created_at"
  t.datetime "updated_at"
end

为记录创建属性的默认方式是通过单个文本字段完成,但是您可能知道,相册有多个轨道,这需要多个文本字段来列出轨道。默认情况下,我计划允许用户显示12个空白字段,以便在需要时添加/减去曲目(在 fiddle 中找到一个粗略示例)。

我已经开始研究嵌套的模型表单了,但是对于想要做一些简单事情的初学者来说,目前的railscast(s)和教程似乎很复杂。有人可以告诉我如何使用给定的信息构建我的控制器和视图,同时结合这个javascript功能吗?

2 个答案:

答案 0 :(得分:1)

<强>嵌套

相关资源是(供将来参考):

Ryan实现你所寻找的东西的方式有点过时了,我希望能给你一些关于如何使用Ajax的想法。首先,让我解释一下这个过程,然后我将解释我发现它的最佳工作方式:

  
      
  1. 以“传统”方式创建表单
  2.   
  3. 你有某种“模块化”方式来创建额外的字段
  4.   
  5. 您创建了一种将这些字段添加到表单的机制
  6.   

这将使您能够根据需要追加字段。 Ryan Bates以稍微过时的方式做事 - 使用javascript附加预渲染字段。这是非常紧缩的,因为它阻止您能够添加任意数量的字段

-

这就是我们所做的(我们使用Ajax。抱歉,我们为此提供的资源已经从网上消失了):

#app/models/album.rb
class Album < ActiveRecord::Base
   has_many :tracks

   def self.build
      album = self.new
      album.tracks.build
   end
end

#app/models/track.rb
class Track < ActiveRecord::Base
   belongs_to :album
end

#config/routes.rb
resources :albums do
  get :add_field, on: :collection
end

#app/controllers/albums_controller.rb
class AlbumbsController < ApplicationController
   def new
      @album = Album.build
   end

   def add_field
      @album = Album.build
      render "form", layout: false
   end
end

这将使您能够创建以下视图:

#app/views/albums/new.html.erb
<%= form_for @album do |f| %>
   <%= f.text_field :name %>
   <%= render partial: "fields", locals: { f: f } %>
   <%= link_to "Add Field", add_field_path, method: :get, remote: true, id: "add" %>
   <%= f.submit %>
<% end %>

#app/views/albums/_fields.html.erb
<%= f.fields_for :tracks, child_index: Time.now.to_i do |r| %> #-> child_index is the most important part
   <%= r.text_field :title %>
<% end %>

#app/views/albums/form.html.erb
<%= form_for @album do |f| %>
   <%= render partial: "fields", locals: { f: f } %>
<% end %>

最后,这将使您能够执行以下操作:

#app/assets/javascripts/application.js
$(document).on("ajax:success", "#add", function(data){
   $("#form").append(data);
});

答案 1 :(得分:-1)

让事情尽可能简单是一个好主意。

  1. 我建议将专辑和曲目(而不是曲目列表)作为模型,并使用一个包含许多曲目的专辑。曲目列表只是曲目的集合,每个曲目都应该是他们自己的记录。

  2. 在客户端,我建议您先为自己想要采取的每项操作设置单独的表单。因此,不要为专辑创建嵌套表单,而是使用一个表单,允许您为专辑创建单个曲目。

  3. 控制器/智能视图我会使用脚手架为相册提供的内容,并让show动作呈现该专辑的曲目列表以及为该专辑创建新曲目的表单。

  4. 希望这有助于您获得良好的开端!