Rails создается для has_many через ассоциацию с дополнительными атрибутами? - PullRequest
8 голосов
/ 02 декабря 2011

Как создать поля формы для ассоциации has_many :through с дополнительными атрибутами?

В отношении has_many :through есть дополнительный столбец с именем weight.

Вот файл миграциидля таблицы соединения:

create_table :users_widgets do |t|
  t.integer :user_id
  t.integer :widget_id
  t.integer :weight

  t.timestamps
end

Модели выглядят так:

User
  has_many :widgets, :through => :users_widgets,
           :class_name => 'Widget',
           :source => :widget
  has_many :users_widgets
  accepts_nested_attributes_for :widgets # not sure if this is necessary


Widget
  has_many :users, :through => :users_widgets,
           :class_name => 'User',
           :source => :user
  has_many :users_widgets
  accepts_nested_attributes_for :users # not sure if this is necessary


UsersWidget
  belongs_to :user
  belongs_to :widget

Для простоты, Widget и User имеют только одно собственное поле под названием name,ergo User.first.name и Widget.first.name

Вопросы:

  • Как бы добавить выпадающий выбор для виджетов с соответствующим весом для пользователясоздать / редактировать форму?

  • Как динамически добавлять дополнительные формы виджетов к пользователям или формы пользователей к виджетам, чтобы легко добавлять или удалять эти отношения?Камень nested_form_for кажется идеальным решением, но я не смог заставить его работать.

  • Помимо моделей и частичных форм, есть ли какие-то изменения, которые требуютбыть внесенным в мой контроллер?


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

Я использую Rails 3.1 и simple_form 2.0.0dev для генерации моих форм.

Ответы [ 3 ]

6 голосов
/ 17 декабря 2011

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

Ваше буквально не включено, но не так сложно извлечь из него. В вашей модели вы должны написать:

class User 
  has_many :users_widgets
  has_many :widgets, :through -> :user_widgets

  accepts_nested_attributes_for :user_widgets, :reject_if => :all_blank, :allow_destroy => true

  #...
end

Затем вам нужно создать частичное представление, которое будет перечислять ваши ссылки UserWidgets. Поместите эту часть в файл с именем users/_user_widget_fields.html.haml:

.nested-fields
  = f.association :widget, :collection => Widget.all, :prompt => 'Choose an existing widget'
  = f.input :weight, :hint => 'The weight will determine the order of the widgets'
  = link_to_remove_association "remove tag", f

В вашем users/edit.html.haml вы можете написать:

= simple_form_for @user do |f|
  = f.input :name

  = f.simple_fields_for :user_widgets do |user_widget|
    = render 'user_widget_fields', :f => user_widget
  .links
    = link_to_add_association 'add widget', f, :user_widgets

Надеюсь, это поможет.

6 голосов
/ 13 декабря 2011

база вашего вопроса.Я сделал простое приложение.Источник здесь: https://github.com/yakjuly/nest_form_example Я развернул его на heroku, вы можете открыть страницу: http://glowing -lightning-1954.heroku.com / users / new

ответы

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

  2. Я смешиваю "nested_form"в плагине" bootstrap-rails "вы можете добавить nested_fields проще

  3. в моем примере вам нужно добавить вызовы action select и заставить WidgetsController # create can responsesed_with: js

код основан на simple_form, вы можете попробовать.

0 голосов
/ 06 июня 2013

Большое спасибо за указатель кокона nathanvda.Я почесал голову о некоторых проблемах, которые у меня возникали при попытке реализовать это под rails 4.0.0-rc1, и я подумал, что поделюсь своими выводами на случай, если у кого-то возникнут те же проблемы при попытке использования этих udner rails4.

Используя приведенный выше код в качестве примера, я добавил user_id и widget_id к разрешенным параметрам, поскольку они сохраняются в соединительной таблице user_widgets.В rails 3 вы должны были добавить их к attr_accesible в пользовательской модели, но в rails 4 вы должны добавить их к разрешенным параметрам в контроллере основной модели, которую вы используете для вложения, так что здесь это будет users_controller:

params.require(:user).permit(...user_fields...,  
  user_widgets_attributes: [:user_id, :widget_id])

Делая только это, вы сталкиваетесь с несколькими проблемами:

  1. Каждая ассоциация (виджет) умножается при обновлении пользовательской записи.1 становится 2, 4, 8 и т. Д. При обновлении и сохранении записи.
  2. удаление ассоциации не работает, поле удаляется из формы, но связь остается в БД.

Чтобы исправить эти проблемы, вам также необходимо добавить: id и: _destroy в список разрешенных атрибутов:

params.require(:user).permit(...user_fields...,  
  user_widgets_attributes: [:user_id, :widget_id, :id, :_destroy])

, после этого он работает без сбоев.

Juergen

PS: На данный момент вы должны использовать репозиторий git в своем Gemfile, чтобы использовать кокон под rails 4, пока не будет выпущен совместимый с rails 4 гем.Спасибо за электронную почту nathanvda в моем сообщении об ошибке !!

...