web-dev-qa-db-ja.com

accepts_nested_attributes_forとhas_many =>:throughオプション

2つのモデル、リンクとタグがあり、3つ目のlink_tagsを介して関連付けられています。次のコードは私のリンクモデルにあります。

協会:

_class Link < ActiveRecord::Base
  has_many :tags, :through => :link_tags
  has_many :link_tags

  accepts_nested_attributes_for :tags, :allow_destroy => :false, 
  :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end

class Tag < ActiveRecord::Base
  has_many :links, :through => :link_tags
  has_many :link_tags
end

class LinkTag < ActiveRecord::Base
  belongs_to :link
  belongs_to :tag
end
_

links_controllerアクション:

_  def new
    @link = @current_user.links.build
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @link }
    end
  end

  def create
    @link = @current_user.links.build(params[:link])

    respond_to do |format|
      if @link.save
        flash[:notice] = 'Link was successfully created.'
        format.html { redirect_to links_path }
        format.xml  { render :xml => @link, :status => :created, :location => @link }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @link.errors, :status => :unprocessable_entity }
      end
    end
  end
_

New.html.erbのコードを表示します。

_<% form_for [current_user, @link], :url => account_links_path do |f| %>
<%= render :partial => "form", :locals => { :f => f } %>
<% end %>
_

そして対応する部分:

_  <%= f.error_messages %>

  <p>
    <%= f.label :uri %><br />
    <%= f.text_field :uri %>
  </p>
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>

  <h2>Tags</h2>
  <% f.fields_for :tags_attributes do |tag_form| %>
  <p>
    <%= tag_form.label :name, 'Tag:' %>
    <%= tag_form.text_field :name %>
  </p>
  <% unless tag_form.object.nil? || tag_form.object.new_record? %>
  <p>
    <%= tag_form.label :_delete, 'Remove:' %>
    <%= tag_form.check_box :_delete %>
  </p>
  <% end %>
  <% end %>

  <p>
    <%= f.submit 'Update' %>
  </p>
_

次のコード行は、リンクコントローラーの作成アクションでエラーをスローします。

_@link = @current_user.links.build(params[:link])
_

エラー:Tag(#-621698598) expected, got Array(#-609734898)

Has_many =>:throughケースで追加の手順が必要ですか?これらは、基本的なhas_manyの場合に示されている唯一の変更のようです。

27
Andrew C

コードの行を見てください

<% f.fields_for :tags_attributes do |tag_form| %>

:tagsではなく:tags_attributesのみを使用する必要があります。これはあなたの問題を解決します

あなたのようなコントローラにビルドリンクとタグがあることを確認してください

def new
  @link = @current_user.links.build
  @link.tags.build
end
8
Jyothu

私はこれをstackoverflowでここに見つけました:

hails_many:throughを使用したRailsのネストされたフォーム、結合モデルの属性を編集する方法?

うまくいったかどうか教えてください。

5
Tiago

これを機能させるには、適切なparamsハッシュを渡す必要があります。

params = {
  :link => {
    :tags_attributes => [
      {:tag_one_attr => ...}, {:tag_two_attr => ...}
    ],
    :link_attr => ...
  }
}

そしてあなたのコントローラーは次のようになります:

def create
  @link = Link.create(params[:link]) # this will automatically build the rest for your
end
2
jaredonline

これを試して:

<% f.fields_for :tags_attributes do |tag_form| %>
1
obiwanchinobi

試す

<% f.fields_for :tags do |tag_form| %> 

(つまり、:tag_attributesの_attributesを失います)これが私が通常ネストしたフォームを実行した方法です

0
soheildb

コントローラまたはビューでタグを作成する必要があります

def new
  @link = @current_user.links.build
  @link.tags.build
end

#in your view you can just use the association name
<% f.fields_for :tags do |tag_form| %>
0
Aaron Renoir

(フォームのパーシャルをロードする)新しいアクションのコントローラーで、リンクを介して@タグを作成していますか?

だからあなたは次の線に沿って何かを見るはずです:

@link = Link.new
@tag = @link.tags.build

新しいコンテンツを投稿して、links_controllerのアクションを作成するのが最善です。

0
Steve