Ассоциация 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
  ...