【问题标题】:Model form within another model's form in Ruby on RailsRuby on Rails 中另一个模型形式中的模型形式
【发布时间】:2014-06-23 15:56:04
【问题描述】:

我有一个Content 模型、一个Playlist 模型和一个名为PlaylistItem 的模型中的连接关联。

这就是它们的连接方式:

class Content < ActiveRecord::Base
  has_many :playlist_items
  has_many :playlists, through: :playlist_items
end

class Playlist < ActiveRecord::Base
  has_many :playlist_items, -> { order 'position ASC' }
  has_many :contents, through: :playlist_items
end

class PlaylistItem < ActiveRecord::Base
  belongs_to :content
  belongs_to :playlist
end

当我编辑Playlist 时,表单只显示其字段Name,这是它拥有的唯一属性。但我希望能够在该表单中将Content 添加到Playlist(在某个position 中,这是PlaylistItems 唯一的属性)。

我该怎么做?


这是我现在拥有的代码:

<%= form_for(@playlist) do |f| %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>

  <%= f.fields_for :playlist_items do |builder| %>
        <fieldset>
          <%= builder.label :content, "Content ID" %><br>
          <%= builder.text_area :content_id %>
        </fieldset>
  <% end %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

【问题讨论】:

  • 我已经看到了,但我无法正确理解。
  • 您能否在问题中添加到目前为止您的表单中的内容?
  • 好的。我已经把它放在那里了。
  • Content 模型有什么属性,即contents 表中有哪些列。此外,您想从表单中现有的contents 中进行选择,还是在其中创建和/或contents

标签: ruby-on-rails ruby forms model associations


【解决方案1】:

首先,您可以让Playlist 模型接受playlist_items 的嵌套属性。

class Playlist < ActiveRecord::Base
  has_many :playlist_items, -> { order 'position ASC' }
  has_many :contents, through: :playlist_items
  accepts_nested_attributes_for :playlist_items
end

然后,您可以将content_id 添加为集合选择,这将为每个播放列表项创建内容的下拉选择。

<%= f.fields_for :playlist_items do |builder| %>
  <%= builder.label :position %><br>
  <%= builder.integer :position %><br>
  <%= builder.label :content %><br>
  <%= builder.collection_select :content_id, @contents, :id, :title, include_blank: 'Please Select' %>
<% end %>

最后,在您的控制器中,您需要允许将播放列表项属性作为参数传递,并设置您的 @contents 实例变量。

class PlaylistController < ApplicationController
  before_action :load_contents, only: [:new, :edit]

  def edit
    @playlist = Playlist.find(params[:id])
    # Build 10 playlist_items to be added to your playlist
    10.times do; @playlist.playlist_items.build; end
  end

  private
    def load_contents
      @contents = Content.all # or another query to get the specific contents you'd like
    end

    def playlist_params
      params.require(:playlist).permit(:name, playlist_items_attributes: [:id, :position, :content_id])
    end
end

请记住,您需要构建您想使用的每个播放列表项。您可以根据需要在 newedit 方法中执行此操作。

【讨论】:

  • 谢谢。这几乎是我想要的。但是如何在这里添加一个新的 playlist_item 呢?我的意思是,播放列表的内容?它只允许我编辑那些已经存在的。
  • 最简单的方法是执行10.times do; @playlist.playlist_items.build; end 之类的操作,并且总是有10 个额外的playlist_items
  • 我不明白,抱歉。你能说得更具体点吗?
  • 在设置 @playlist 实例变量后,将代码的 sn-p 添加到 PlaylistController 中的 update 方法中。
  • 如果你想要一个按钮或链接来添加一个新的playlist_item,那会有点复杂。我建议您查看Nested Form Railscast 以获取相关帮助。您还可以查看嵌套形式 gems,例如 nested_formcocoonawesome_nested_fields
猜你喜欢
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
相关资源
最近更新 更多