Ответ 1
Я вижу в вашей второй вложенной форме нет link_to_add_association
.
Внутри кокона link_to_add_association
создает новый элемент, когда пользователь хочет динамически его добавить.
Или вы подразумеваете, что после создания sale_vehicle
он должен автоматически содержать vehicle
? Я бы предположил, что пользователь должен будет выбрать продаваемый автомобиль?
У меня есть тестовый проект, который демонстрирует двойные вложенные формы: у проекта есть задачи, которые могут иметь подзадачи.
Но, может быть, это не так хорошо относится к тому, что вы хотите сделать?
Вы не показываете свои модели, но если я правильно понимаю отношения,
sale
has_many :sale_vehicles
sale_vehicle
has_one :vehicle (has_many?)
Итак, если у вас есть sale_vehicle
, у которого может быть vehicle
, тогда я бы предположил, что ваш пользователь сначала добавит sale_vehicle
в sale
, а затем нажмите ссылку, чтобы добавить vehicle
. Это то, что кокон может делать отлично. Если, с другой стороны, вы хотите, чтобы при динамическом создании кокона sale_vehicle
был создан a vehicle
, я вижу несколько разных параметров.
Используйте after_initialize
Не могу сказать, что я настоящий фанат этого, но в обратном вызове after_initialize
вашего sale_vehicle
вы всегда можете создать требуемую модель vehicle
.
Я предполагаю, что, так как ваш sale_vehicle
недействителен/не может существовать без модели vehicle
, то ответственность за возможность создания вложенной модели сразу после сборки будет отвечать.
Обратите внимание, что after_initialize
выполняется для каждого создания объекта, поэтому это может быть дорогостоящим. Но это может быть быстрым решением. Если вы отклоняете пустые вложенные модели, это должно работать imho.
Использование Decorator/Presenter
Для пользователя sale_vehicle
и vehicle
кажутся одним объектом, поэтому почему бы не создать декоратор, состоящий из sell_vehicle и транспортного средства, который представлен в одну (вложенную) форму и при сохранении этого, декоратор знает, что его нужно сохранить в правильные модели.
Примечание: для этого существуют разные термины. Декоратор обычно только расширяет один класс с помощью некоторых методов просмотра, но он может также быть композицией разных моделей. Альтернативные термины: презентатор, модель просмотра.
Во всяком случае, функция декоратора/презентатора - это абстрагирование основной базы данных для ваших пользователей. Таким образом, по какой-то причине вам нужно было разделить один объект на две модели базы данных (например, чтобы ограничить количество столбцов, чтобы сохранить читаемые модели...), но для пользователя он все еще является единственным объектом. Итак, "представляйте" его как единое целое.
Разрешить кокон вызывать пользовательский метод build
Не уверен, что я поклонник этого, но это определенно есть возможность. Он уже поддерживается, если "вложенная модель" не является ActiveRecord:: Association, поэтому это не должно быть слишком сложно добавить. Но я не согласен с этим дополнением. Все эти параметры усложняют работу.
EDIT: простейшее исправление
Внутри частичного просто создайте необходимый дочерний объект. Это должно произойти до fields_for
, и тогда вам хорошо идти. Что-то вроде
<% f.object.build_vehicle %>
<%= f.fields_for :vehicle do |vehicle_builder| %>
<%= render :partial => "vehicles/form", :locals => {:f => vehicle_builder, :f_parent => f, :form_actions_visible => false, :show_features => true, :fieldset_label => 'Vehicle Details'} %>
<% end -%>
Заключение
Мне лично очень нравится подход декоратора, но он может быть немного тяжелым. Просто создайте объект перед рендерингом вызова fields_for
, таким образом вы всегда уверены, что есть хотя бы один.
Мне интересно услышать ваши мысли.
Надеюсь, это поможет.