Ассоциация Simple_Form с has_many: через дополнительное поле
У меня две модели: разработчики и задачи,
class Developer < ActiveRecord::Base
attr_accessible :address, :comment, :email, :name, :nit, :phone, :web
has_many :assignments
has_many :tasks, :through => :assignments
end
class Task < ActiveRecord::Base
attr_accessible :description, :name, :sprint_id, :developer_ids
has_many :assignments
has_many :developers, :through => :assignments
end
class Assignment < ActiveRecord::Base
attr_accessible :accomplished_time, :developer_id, :estimated_time, :status, :task_id
belongs_to :task
belongs_to :developer
end
im, заботясь об отношении, добавив таблицу присваивания, поэтому я могу добавить многих разработчиков к одной задаче, в частности, теперь я также хотел бы иметь возможность манипулировать другими полями, добавленными в таблицу соединения, например "оцененное_time" ',' done_time '... и т.д.... что я получил от моего Simple_form
`
<%= simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.association :developers, :as => :check_boxes %>
<div class="form-actions">
<%= f.button :submit, :class => 'btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
project_sprint_path(@sprint.project_id,@sprint), :class => 'btn' %>
</div>
<% end %>`
Это только позволяет мне выбирать разработчиков, я хочу, чтобы там было возможно изменить поле оценочного времени.
Любые предложения?
Ответы
Ответ 1
Мне нравится, как простая форма имеет помощников ассоциации, что делает ее очень простой в некоторых случаях. К сожалению, то, что вы хотите, вы не можете решить с помощью простой формы.
Для этого вам нужно создать assignments
.
Существует два возможных подхода.
Для обоих вы должны добавить в свою модель следующее:
class Task
accepts_nested_attributes_for :assignments
end
Обратите внимание, что если вы используете attr_accesible
, вы также должны добавить к нему assignments_attributes
.
Легкий подход
Предположим, вы знаете, сколько заданий, максимально, task
. Предположим, что 1 для простоты.
В вашем контроллере напишите
def new
@task = Task.build
@task.assignments.build
end
Это позволит убедиться, что есть одно новое назначение.
По вашему мнению напишите:
= simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f|
= f.input :name
= f.input :description
= f.simple_fields_for :assignments do |assignment|
= assignment.association :developer, :as => :select
= assignment.estimated_time
.form-actions
= f.button :submit, :class => 'btn-primary'
= link_to t('.cancel', :default => t("helpers.links.cancel")),
project_sprint_path(@sprint.project_id,@sprint), :class => 'btn'
Проблема с этим подходом: что, если вы хотите больше 1, 2 или 3?
Использовать кокон
Cocoon - это драгоценный камень, который позволяет создавать динамические вложенные формы.
Ваше мнение будет выглядеть следующим образом:
= simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f|
= f.input :name
= f.input :description
= f.simple_fields_for :assignments do |assignment|
= render `assignment_fields`, :f => assignment
.links
= link_to_add_association 'add assignment', f, :assignments
.form-actions
= f.button :submit, :class => 'btn-primary'
= link_to t('.cancel', :default => t("helpers.links.cancel")),
project_sprint_path(@sprint.project_id,@sprint), :class => 'btn'
И определите частичный _assignment_fields.html.haml
:
.nested_fields
= f.association :developer, :as => :select
= f.estimated_time
= link_to_remove_association 'remove assignment', f
Надеюсь, что это поможет.
Ответ 2
Дело в том, что с помощью этого:
<%= f.association :developers, :as => :check_boxes %>
Фактически вы устанавливаете только атрибут developer_ids, который автоматически будет создавать назначения для вас, поскольку он имеет много: через. Для этого я считаю, что вы, вероятно, должны использовать вложенные атрибуты для каждой из назначений, и каждая запись будет иметь поле выбора или подобное, чтобы выбрать соответствующего разработчика для этого конкретного назначения в этой задаче. Это очень похоже на то, что ответил Коджонес, но вы не должны использовать флажки для этой ассоциации, так как вы собираетесь иметь дело с одним присваиванием, которое содержит одного разработчика. И с вложенными атрибутами вы должны иметь возможность создавать столько назначений, которые вы хотите.
Я считаю, что это самый простой способ начать.
Ответ 3
Я думаю, что это должно выглядеть примерно так:
= f.simple_fields_for :assignments do |fa|
= fa.association :developer, as: :check_boxes
= fa.input :estimated_time
...