Как отобразить форму для подмножества связанных записей, некоторые из которых еще не существуют? - PullRequest
5 голосов
/ 02 февраля 2011

У меня есть задачи и пользователи. Когда пользователь завершает задачу, я создаю Завершение, в котором есть поле для пользователя, чтобы указать, сколько времени они провели. Мне нужна форма, которая показывает все задачи с их статусом завершения и атрибутом time_spent. После отправки существующие дополнения должны быть обновлены, а новые должны быть созданы. Я хотел бы сделать это в Formtastic, если это возможно, но я буду доволен базовым решением на Rails 3.

class Completion < ActiveRecord::Base
  belongs_to :task
  belongs_to :user

  # attribute time_spent
end

class User < ActiveRecord::Base
  has_many :completions
  has_many :tasks, :through => :completions
end    

class Task < ActiveRecord::Base
  belongs_to :milestone
  has_many :completions
  has_many :users, :through => :completions
end

Дополнительным аспектом является то, что я хочу показать только определенный набор задач, например, относящихся к этапу. Нужно ли мне иметь форму на контроллере Milestone, которая отправляет сообщения на контроллер Completions?

class Milestone < ActiveRecord::Base
  has_many :tasks
  has_many :completions, :through => :tasks
end

UPDATE Я искал несколько дней и нашел многих мертвых концов . Это Несколько объектов в форме Rails близко, но для этого требуется, чтобы все связывающие объекты уже существовали.

Что выделяет этот вопрос, так это то, что некоторые ссылки еще не существуют, и нет единой модели для размещения ссылок. Например. С постом Райана Дейгла «Вложенные объектные формы» *1020*) я выполнил эту работу в форме для редактирования всех возможных завершений для пользователя, но мне нужно отредактировать подмножество возможных завершений в одной форме. Нужно ли создавать избыточный объект MilestoneCompletions, который has_many Completions и belongs_to User? Может ли ActiveModel has_many?

Ответы [ 2 ]

5 голосов
/ 08 февраля 2011

Я наконец-то решил это.Одним из ключей является аргумент коллекции fields_for .Другой - генерировать коллекцию из смеси существующих и новых записей.

Итак, в представлении что-то вроде:

<%= form_for @user do |f| %>
  <table>
    <tr><th>Completed</th><th>Time spent</th><th>Task</th></tr>

    <%= f.fields_for :completions, available_completions_for_milestone(@user, @milestone) do |cf| %>
      <tr>
        <td><%= cf.check_box :status, {disabled: cf.object.persisted?}, "done", "unreported" %></td>
        <td><%= cf.text_field :time_spent_text %></td>
        <td><%= cf.object.task.description %></td>
      </tr>
      <%= cf.hidden_field :task_id %>
    <% end -%>

С помощью вспомогательного метода:

def available_completions_for_milestone(user, milestone)
  user_completions = user.completions.in_milestone(milestone)    
  available = []
  milestone.tasks.each do |t|
    c = user_completions.select{|c| c.task_id == t.id}.first
    if !c then # make it
      c = user.completions.build( task: t )
    end
    available << c
  end
  available
end

Обратите внимание на то, что дополнения, уже находящиеся в БД, проверяются и отключаются, поэтому их нельзя проверять.Не проверенное состояние получает значение «unreported», и модель User может отфильтровывать эти записи, чтобы они не помещались в БД:

has_many :completions
accepts_nested_attributes_for :completions, :reject_if => proc { |attrs| attrs['status'] == 'unreported' }

Я также должен был сделать completions_attributes attr_accessible в модели User,Если вы сделаете task_ids доступным, тогда update удалит завершения, которые были исключены из PUT.

0 голосов
/ 04 февраля 2011

Я отвечаю на это как возможное решение для любых других читателей, но оно не удовлетворяет, поэтому я не отмечаю его как приемлемое.

Чтобы обойти это, в действии генерации формыЯ просто create пропустил все ассоциации в неактивном состоянии.(Добавив поле status к модели Completion.) Затем я использую функцию редактирования массива object [].Во 2-м комментарии к RISCfuture есть несколько полезных советов по документам form_for API .

...