Вложенные формы в Rails с использованием has_many: through

Мне сложно понять, как создать вложенную форму с помощью отношения has_many: through. Я использовал этот Railscast и взглянул на это руководство и множество вопросов в Stack Overflow и в других местах в Google.

Я пытаюсь создать способ создания тегов через форму статей. Мой код прошел множество итераций на основе информации из множества разных источников, и ни один из них не работал, но сейчас у меня есть

Класс для статей

class Article < ActiveRecord::Base
    attr_accessible :content, :heading, :image, :tag_ids, :tags, :tag_name, :tag_attributes

  belongs_to :user
  has_many :comments, :dependent => :destroy
  has_many :article_tags
  has_many :tags, :through => :article_tags
  accepts_nested_attributes_for :tags, :reject_if => proc { |attributes| attributes['tag_name'].blank? }
...
end

Класс для тегов

class Tag < ActiveRecord::Base
  attr_accessible :tag_name

  has_many :article_tags
  has_many :articles, :through => :article_tags
end

Класс для article_tags

class ArticleTag < ActiveRecord::Base
  belongs_to :article
  belongs_to :tag
end

Новое в моем article_controller.rb выглядит так:

def new
  @article = Article.new
  @tags = Tag.find(:all)
  article_tag = @article.article_tags.build()
  @article_tags = @article.tags.all
  @article.article_tags.build.build_tag
  3.times do
      article_tag = @article.article_tags.build()
  end
end

И моя форма для статей в настоящее время выглядит так (я ходил туда-сюда между вложением тегов fields_for: внутри fields_for: article_tags или просто позволяя им быть самими собой):

<%= form_for @article , :html => { :multipart => true } do |f| %>
 ...excerpted...
<%= f.fields_for :article_tags do |t| %>
  <%= t.fields_for :tags do |ta| %>
    <%= ta.label :tag_name, "Tag name" %>
    <%= ta.text_field :tag_name %>
  <% end %>
<% end %>

Я понимаю, что это, вероятно, беспорядок; Я новичок в этом и пытаюсь понять это. Нужно ли мне что-то добавлять в файл article_controller create? Это как-то связано с attr_accessible? Или мне сделать что-то совсем другое?

РЕДАКТИРОВАТЬ:

Вот параметры запроса после внесения изменения, предложенного Hck, и создания новой статьи, выбора существующего тега с tag_id 3 и попытки одновременно создать новый тег:

Запущен POST "/ article" для 127.0.0.1 в 2011-08-10 19:05:46 +1000 Обработка с помощью ArticlesController # create as HTML Параметры: {"utf8" => "✓", "Authentity_token" => "5CQuV4RWfFZD1uDjv1DrZbIe + GB / sDQ6yiAETZutmZ4 = "," article "=> {" heading "=>" Тестовый заголовок "," content "=>" Test Content "," tag_ids "=> [" 3 "]," article_tags "=> {" tags "=> {" tag_name "=>" Test tag "}}}," commit "=>" Submit "} Загрузка пользователя (0,2 мс) ВЫБРАТЬ" users ". * FROM" users "WHERE" users "." id "= 1 LIMIT 1 ПРЕДУПРЕЖДЕНИЕ. Невозможно массово назначить защищенные атрибуты: article_tags Tag Load (0,4 мс) SELECT" tags ". * FROM" tags "WHERE" tags "." Id "= 3 LIMIT 1 AREL (0.4ms) INSERT INTO "article" ("content", "user_id", "created_at", "updated_at", "heading", "image_file_name", "image_content_type", "image_file_size") ЗНАЧЕНИЯ ('Test Content', 1, '2011- 08-10 09: 05: 46.228951 ',' 2011-08-10 09: 05: 46.228951 ',' Заголовок теста ', NULL, NULL, NULL) AREL (0,2 мс) INSERT INTO "article_tags" ("article_id", " tag_id "," created_at "," updated_at ") ЗНАЧЕНИЯ (88, 3, '2011-08-10 09: 05: 46.243076 ',' 2011-08-10 09: 05: 46.243076 ') [скрепка] Сохранение вложений. Перенаправлен на [localhost] Завершено 302 Найдено за 212 мс

И если я добавлю: article_tags в attr_accessible для Article и попробую еще раз, я получу:

Запущен POST "/ article" для 127.0.0.1 в 2011-08-10 19:11:49 +1000 Обработка с помощью ArticlesController # create as HTML Parameters: {"utf8" => "✓", "Authentity_token" => "5CQuV4RWfFZD1uDjv1DrZbIe + GB / sDQ6yiAETZutmZ4 = "," article "=> {" heading "=>" Тестовый заголовок "," content "=>" Тестовый контент "," tag_ids "=> [" 3 "]," article_tags "=> {" tags "=> {" tag_name "=>" Test tag "}}}," commit "=>" Submit "} Загрузка пользователя (0,2 мс) ВЫБРАТЬ" users ". * FROM" users "WHERE" users "." id "= 1 LIMIT 1 Tag Load (0.4ms) SELECT" tags ". * FROM" tags "WHERE" tags "." Id "= 3 LIMIT 1 Завершено за 119 мс

ActiveRecord :: AssociationTypeMismatch (ArticleTag (# 2165285820) ожидается, получен массив (# 2151973780)): app / controllers / article_controller.rb: 32: в `create '


person Kelly    schedule 09.08.2011    source источник


Ответы (2)


Попробуйте заменить @article.article_tags.build.build_tag на @article.tags.build в действии вашего контроллера.

person Hck    schedule 09.08.2011
comment
Спасибо, но все равно не сработало. Он создает новую статью без ошибок, но новый тег не создается и не назначается. - person Kelly; 09.08.2011
comment
Отправьте параметры запроса после отправки формы, пожалуйста. - person Hck; 09.08.2011
comment
Я отредактировал свой вопрос; дайте мне знать, если вы это не то, что искали. Спасибо, что посмотрели. - person Kelly; 10.08.2011

Не думаю, что в него тоже нужно вкладывать теги статей. Теги статей - это просто ассоциация между статьями и тегами. Вы можете просто создать новый тег в статьях, потому что вы уже связались с ними. Я считаю, что это из-за магии «accept_nested_attributes». попробуй это.

<%= form_for @article , :html => { :multipart => true } do |f| %>
 ...excerpted...
  <%= f.fields_for :tags, Tag.new do |t| %>
    <%= t.label :tag_name, "Tag name" %>
    <%= t.text_field :name %>
  <% end %>
<% end %>

Кроме того, вы должны попытаться назначить его массово, вместо того, чтобы сохранять каждый атрибут по частям, используя частные параметры. У меня тоже была проблема с вложенными формами, поэтому вы можете посмотреть, как я написал свой код: Невозможно сохранить запись во вложенных формах RAILS

Единственное, что я оставил там, это раздел приватных параметров, который я рекомендовал вам сделать.

private
    def venue_params
      params.require(:venue).permit(:name, :address, :discount, :latitude, :longitude, :tags_attributes =>[:name],:tag_ids => [])
    end

Я также написал в блоге сообщение о вложенных формах, так что вы тоже можете взглянуть на него

http://minling.github.io/

person cats    schedule 03.11.2015