【问题标题】:rails 4 collection_select multiple nested attributes not saving properlyrails 4 collection_select多个嵌套属性未正确保存
【发布时间】:2015-02-12 02:04:40
【问题描述】:

我是 Rails 新手,在使用 collection_select 保存连接表的嵌套属性时遇到问题。我有模型 post、tag 和 post_tagging。 post_tagging 是一个连接表。

我想为每个帖子设置多个标签,所以我尝试通过 collection_select 使用多选,但是当我保存时,只有 post_id 被插入到数据库中。下面是我的代码和日志。

Post.rb

class Post < ActiveRecord::Base
  has_many :post_taggings, foreign_key: :post_id, dependent: :destroy
  has_many :tags, through: :post_taggings, source: :tag
  accepts_nested_attributes_for :post_taggings, reject_if: :all_blank, allow_destroy: true
end

标签.rb

class Tag < ActiveRecord::Base
  has_many :post_taggings, foreign_key: :tag_id, dependent: :destroy
  has_many :posts, through: :post_taggings, source: :post
end

post_tagging.rb(我在 post_tagging 模型中关闭了 tag_id 和 post_id 的存在验证,以便获得 POST 的日志。)

class PostTagging < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag

  #validates :post_id, presence: true
  #validates :tag_id, presence: true
end

posts_controller.rb(缩写)

class PostsController < ApplicationController
  def new
    @post = Post.new
    @post.post_taggings.build
  end


  def new_post_params
    params.require(:post).permit(:title, post_taggings_attributes: { :tag_id => [] })
  end

  def update_post_params
    params.require(:post).permit(:title, post_taggings_attributes: [ { :tag_id => [] }, 
                                                               :id, :_destroy ])
  end
end

views/post/new.html.erb

<%= form_for(@post) do |f| %>
<%= f.fields_for :post_taggings do | pt | %> 
    <%= pt.label :post_taggings, "Tags" %><br />
    <%= pt.collection_select(:tag_id, Tag.all, :id, :name, {include_hidden: false}, {multiple: true} ) %><br />
<% end %>

HTML

<select id="post_post_taggings_attributes_0_tag_id" multiple="multiple" name="post[post_taggings_attributes][0][tag_id][]">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
  <option value="5">5</option>
  <option value="6">6</option>
  <option value="7">7</option>
  <option value="8">8</option>
  <option value="9">9</option>
  <option value="10">10</option>
</select>

当我保存表单时,我得到以下信息:

Started POST "/posts" for 127.0.0.1 at 2014-12-13 04:22:19 -0800
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"DaeMJb5b4PcLUz2YfQCjYk1r7pzcMd3NOmhYwEExz2U=", "post"=>{"title"=>"The Title", "post_taggings_attributes"=>{"0"=>{"tag_id"=>["1", "2", "6"]}}}, "commit"=>"Create Post"}
  (0.1ms)  begin transaction
  SQL (0.5ms)  INSERT INTO "posts" ("created_at", "title", "updated_at") VALUES (?, ?, ?)  [["created_at", "2014-12-13 12:22:19.789055"], ["title", "The Title"], ["updated_at", "2014-12-13 12:22:19.789055"]]
  SQL (0.4ms)  INSERT INTO "post_taggings" ("created_at", "post_id", "updated_at") VALUES (?, ?, ?)  [["created_at", "2014-12-13 12:22:19.791928"], ["post_id", 16], ["updated_at", "2014-12-13 12:22:19.791928"]]
 (2.2ms)  commit transaction
Redirected to http://localhost:3000/posts/16
Completed 302 Found in 27ms (ActiveRecord: 3.3ms)

由于它不起作用,我知道我做错了什么。我也不相信编辑案例会起作用。

我觉得我很接近,因为如果我更改强参数,它可以与单个选择一起使用

{ :tag_id => [] } 

:tag_id

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 nested-attributes collection-select


    【解决方案1】:

    我更喜欢更方便的方式。

     # in your form
    
     <%= form_for(@post) do |f| %>
    
    ##  your other fields
        <%= f.collection_select(:tag_ids, Tag.all, :id, :name, {include_hidden: false}, {multiple: true} ) %><br />
     <% end %>
    
    #in your controller
     def post_params
      params.require(:post).permit([:title, :tag_ids => []])
     end
    

    现在不是两个不同的允许参数列表,而是两者都适用。删除标签不会很复杂。

    请在您操作的所需位置替换您允许的参数值。

    【讨论】:

    • 您需要允许:tag_ids =&gt; [] 而不是:tag_ids
    • @Rubyrider 感谢您的回答,当我将表单更新为 :tag_ids 并创建/编辑我得到的帖子时:undefined method tag_ids' for #&lt;PostTagging:0x007ff8eb7a2290&gt;
    • tags_ids 也会导致错误。我还缺少其他东西吗?我在模型中的关系不正确吗?
    • 天哪!请将其放入已发布的 f 表单对象中。它应该只适用于 post 对象。
    • 我已经更新了我的答案。在我的示例中签出表格。我很抱歉,它的 tag_ids,而不是 tags_ids。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多