【问题标题】:Rails 3.2.13 - Delete Entry From Nested AttributesRails 3.2.13 - 从嵌套属性中删除条目
【发布时间】:2013-08-10 23:27:53
【问题描述】:

我有一个 Ruby on Rails 3.2.13 应用程序,其中有一个 collection_select 语句。 collection_select 语句在 fields_for 语句中,我从 collection_select 收集选定的 id 并使用它们填充另一个表。我遇到的问题是 collection_select 语句在存储所选 id 集合的数组中添加了一个空 id 条目。

这是我认为的代码:

<%= f.fields_for :media_topics do |media_topic| %>
  <%= media_topic.label :topic, "Topics" %><%= media_topic.collection_select(:topic_id, Topic.order("name_en"), :id, :name_en, {}, {multiple: true}) %>
<% end %>

以下是选择两个选项后数组的外观示例:

"media_topics_attributes"=>{"0"=>{"topic_id"=>["", "2", "47"], "id"=>"1895"}}

我通过另一个 Stack Overflow 成员发现,collection_select 中的空白条目是一个隐藏值,它会自动包含在内。在 Rails 3 中,没有办法不包含该字段。但是,根据我之前的问题Rails 3.2 - collection_select Adding A Null Entry In The First Position Of My Array 的答案中提供的链接,将有一种方法可以在 Rails 4 中排除这个隐藏值。

在我决定第一次使用 Accepts_nested_attributes_for 之前,我跳过了这个值并手动添加了 MediaTopic 行。我想让我的控制器代码比现在更干净。我遇到的问题是弄清楚如何跳过那个空白条目。我已经阅读了 API 和许多其他关于我应该如何能够跳过这个值的帖子,但它们都不起作用。

这是我的 MediaLibrary 模型中 media_topics 嵌套属性的代码。

has_many :media_topics, dependent: :destroy
accepts_nested_attributes_for :media_topics, allow_destroy: true, reject_if: proc { |attributes| attributes['id'].blank? }

collection_select 中的主题模型具有字段 :id,它将更新模型 MediaTopic 中的字段 :topic_id。 MediaTopic 中的另一个字段是 :media_library_id。我在accepts_nested_attributes_for 命令中尝试了idtopic_id 字段,但是当我对主模型执行update_attributes 时,我收到一个错误消息,指出主题不能为空。我确定错误来自尝试为数组中的第一个空白条目创建 MediaTopic 行。

我已经研究了几天,但我没有尝试过。我检查了 API、APIDock 和其他来源无济于事。我想在执行 update_attributes 之前从 media_topics_attributes 中删除空白条目。我想我不明白如何编写代码。我已经在 API 中看到了这个作为示例,但我不知道应该去哪里或者我应该如何编写代码来摆脱空白值。

params = { member: {
  posts_attributes: [{ id: '2', _destroy: '1' }]
}}

任何帮助将不胜感激。

更新 2013 年 8 月 10 日晚上 10:46 CDT

在我的控制器中,在完成所有错误检查后,我的 case 语句中有以下 when 子句。

when @media_library.update_attributes(params[:media_library])

更新 2013 年 8 月 12 日上午 8:20 CDT

在 MediaLibrary 模型中,我将 Accept_nested_attributes_for 更改为以下内容。

accepts_nested_attributes_for :media_topics, allow_destroy: true

更新 2013 年 8 月 12 日上午 10:50 CDT

这是哈希在我的调试中的样子:

media_topics_attributes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
    '0': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
      topic_id:
      - '2'
      - '47'
      id: '1896'

但我仍然收到错误媒体主题主题不能为空。我会继续寻找。

更新 2013 年 8 月 12 日下午 12:15 CDT

Topic 是一个具有名称列表的模型(:id, :name)

MediaLibrary 是我希望能够通过 Topic.name 选择的行列表

MediaTopic 是将 Topic 与 MediaLibrary 相关联的行列表

MediaLibrary has_many :media_topics, 依赖: :destroy

主题 has_many :media_topics

MediaTopic 属于_to :media_library 属于_to :topic

我正在处理的屏幕将对 MediaLibrary 进行更改,并根据列出主题名称的 collection_select 语句更新 MediaTopic。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.2 nested-attributes fields-for


    【解决方案1】:

    在 MediaLibrary 模型中

    alias_method :underlying_media_topics_attributes=, :media_topics_attributes=
    
    def media_topics_attributes=(hash_of_hashes)
      hash_of_hashes.each { |key, hash| hash[:topic_id].reject!(&:blank?) }
      self.underlying_media_topics_attributes=(hash_of_hashes)
    end
    

    【讨论】:

    • bgates,非常感谢您的意见。我在我的问题中添加了如何更新 MediaLibrary,它将同时使用哈希中的有效值更新 media_topics_attributes。我已将您发布的方法添加到 MediaTopic 模型。但是我不确定我会在哪里访问这个方法。我想我应该在我的 MediaLibrary 模型中访问它,但我不确定如何将 media_topic_attributes 传递给它。我会用这种方法替换 :reject_if 子句中的 PROC 吗?我最近上了一堂 Ruby 课,但有时我并不清楚这种表示法:)
    • 我的错误,该方法在 MediaLibrary 模型中。我编辑了最初的答案。
    • 我将该方法移至 MediaLibrary 模型。我发布了关于如何更改模型的更新。我的控制器中的 update_attributes 语句出现错误。 Completed 500 Internal Server Error in 6ms NoMethodError (super: no superclass method media_topics_attributes=' for #&lt;MediaLibrary:0x007f8bd63177e8&gt;): app/models/media_library.rb:73:in media_topics_attributes=' app/controllers/media_libraries_controller.rb:135:in `update' 如果我注释掉 super 没有更新发生。我的 Ruby 中没有示例课堂笔记。我如何引用这个方法以及在哪里(模型或控制器)?谢谢!
    • 我很尴尬。不能打电话给super,因为ActiveRecord 不知道media_topics_attributes= 是什么。我编辑了我的答案;这个我在控制台中测试了一个接受嵌套属性的模型,alias_method 似乎做了我们想要的。
    • 别不好意思。我从你身上学到了很多。您更新的答案中的代码删除了空白条目。检查我的更新。但是我仍然收到错误媒体主题主题不能为空。我在 MediaTopic 模型中验证了 :topic_id, presence: true 。如果我删除它,则会创建一个带有空白 id 的 MediaTopic 行,这会导致我的 collection_select 寻找带有空白 id 的主题行时出现问题。它似乎在 MediaLibrary 之前检查 MediaTopic。 :topic_id 的验证是否可以移动到 MediaLibrary 中,在从哈希中删除空白 id 后进行检查?
    【解决方案2】:

    根据@vinodadhikary 的说法,数组中的 null 条目在 Rails 3 中按预期工作。我最近在 Rails 4 中重写了这个应用程序。我完全重写了逻辑,首先使用 has_many through 关联我的所有表。我还仅使用 collection_select 语句替换了 fields_for 逻辑。我在第一个 {} 中添加了 include_hidden = false ,并且数组中没有出现空条目。几天前我问了一个类似的问题,经过大量搜索后,我想出了一个解决方案。详细信息在下面的链接中。

    Rails 4 - Using collection_select to get an array of ids for an Intermediate Table with Nested Attributes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 2017-12-23
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      相关资源
      最近更新 更多