Вложенные формы в Rails с использованием has_many: through - PullRequest
1 голос
/ 09 августа 2011

У меня проблемы с выяснением, как создать вложенную форму, используя отношение has_many: through. Я использовал этот Railscast и посмотрел на этот учебник и множество вопросов о переполнении стека и в других местах в 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? Это как-то связано с attr_accessible? Или я должен сделать что-то совершенно другое?

EDIT:

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

Запущен POST "/ article" для 127.0.0.1 в 2011-08-10 19:05:46 +1000 Обработка ArticlesController # создать как HTML Параметры: {"utf8" => "✓", "authenticity_token" => "5CQuV4RWfFZD1uDjv1DrZbIe + GB / sDQ6yiAETZutmZ4 =", "article" => {"heading" => «Заголовок теста», «content» => «Test Content» "," tag_ids "=> [" 3 "]," article_tags "=> {" tags "=> {" tag_name "=>" Тестовый тег "}}}," commit "=>" Submit "} Пользовательская нагрузка (0,2 мс) ВЫБЕРИТЕ "users". * FROM "users" WHERE "users". "Id" = 1 LIMIT 1 ВНИМАНИЕ: Не удается массово назначить защищенные атрибуты: article_tags Загрузка тегов (0,4 мс) ВЫБЕРИТЕ "теги". * FROM "теги" ГДЕ "теги". "Id" = 3 LIMIT 1 AREL (0,4 мс) INSERT INTO "article" ("content", "user_id", "creation_at", "updated_at", "heading", "image_file_name", "image_content_type", "image_file_size") VALUES ('тестовое содержимое', 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", "creation_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 for Article и попробую еще раз, я получу:

Запущен POST "/ article" для 127.0.0.1 2011-08-10 19:11:49 +1000 Обработка ArticlesController # создать как HTML Параметры: {"utf8" => "✓", "authenticity_token" => "5CQuV4RWfFZD1uDjv1DrZbIe + GB / sDQ6yiAETZutmZ4 =", "article" => {"heading" => "Заголовок теста", "content" => "Тестовое содержимое "," tag_ids "=> [" 3 "]," article_tags "=> {" tags "=> {" tag_name "=>" Тестовый тег "}}}," commit "=>" Submit "} Пользовательская нагрузка (0,2 мс) ВЫБЕРИТЕ "users". * FROM "users" WHERE "users". "Id" = 1 LIMIT 1 Загрузка тегов (0,4 мс) ВЫБЕРИТЕ "теги". * FROM "теги" ГДЕ "теги". "Id" = 3 LIMIT 1 Завершено в 119 мс

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

Ответы [ 2 ]

0 голосов
/ 03 ноября 2015

Я не думаю, что вы должны вкладывать в него теги статей.Теги статьи - это просто связь между статьями и тегами.Вы можете просто создать новый тег в статьях, потому что вы уже связаны с ними.Я полагаю, что это происходит от магии "accepts_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/

0 голосов
/ 09 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...