2011-02-02 10 views
5

Ho compiti e utenti. Quando un utente completa un'attività, creo un Completamento che ha un campo per indicare all'utente quanto tempo hanno trascorso. Ho bisogno di un modulo che mostri tutte le attività con lo stato di completamento e l'attributo time_spent. Al momento dell'invio, i completamenti esistenti dovrebbero essere aggiornati e nuovi dovrebbero essere creati. Mi piacerebbe farlo in Formtastic se possibile, ma sarò felice con una soluzione Rails 3 di base.Come visualizzare un modulo per un sottoinsieme di record associati, alcuni dei quali non esistono ancora?

Un altro aspetto è che voglio mostrare solo un determinato insieme di attività, come quelle che appartengono a un Milestone. Devo avere un modulo sul controller Milestone che post al controller di Completamenti?

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

UPDATE Ho cercato per giorni e ora ho trovato manydeadends. Questo Multiple objects in a Rails form è chiuso, ma richiede che tutti gli oggetti di collegamento esistano già.

Ciò che distingue questa domanda è che alcuni dei collegamenti non esistono ancora e non esiste un singolo modello per i nidi da annidare. Es. Con Ryan Daigle Nested Object Forms post ho realizzato questo lavoro in un modulo per modificare tutti i possibili completamenti per un utente, ma ho bisogno di modificare un sottoinsieme di possibili completamenti in un unico modulo. Devo creare un oggetto ridondante MilestoneCompletions con i completamenti has_many e l'utente belongs_to? Può un ActiveModel has_many?

+2

Ho appena cancellato la mia risposta per rendere più visibile la tua domanda, modifica la tua domanda con i dettagli che mi hai dato :) – apneadiving

+0

Questo è molto premuroso! Ho dovuto superare questo problema, quindi alla fine ho rinunciato e ho lavorato intorno ad esso. Pubblicherò la mia risposta per chiunque sia interessato. – Turadg

risposta

4

Ho finalmente risolto questo. Una chiave è l'argomento della raccolta su fields_for. L'altro è quello di generare la raccolta con un mix di record esistenti e nuovi.

Così nella vista, qualcosa come:

<%= 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 -%> 

Con un metodo di supporto:

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 

Avviso nel ritenere che completamenti già nel DB sono controllati e disabili in modo da non possono essere deselezionato. Lo stato non selezionato ottiene il valore "non dichiarata" e il modello utente può filtrare i record in modo da non andare nel DB:

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

ho anche dovuto fare completions_attributes attr_accessible sul modello User. Se rendi accessibile task_ids, allora lo update eliminerà i completamenti rimasti fuori dallo PUT.

0

Rispondo a me stesso come a una possibile soluzione per qualsiasi altro lettore, ma non è soddisfacente, quindi non lo contrassegnerò come accettabile.

Per aggirare questo problema, nell'azione di generazione del modulo ho appena create eventuali associazioni mancanti in uno stato 'inattivo'. (Aggiungendo un campo status al modello Completion). Quindi uso la funzione di modifica dell'array "oggetto []" dei moduli. RISCfuture ha alcuni suggerimenti utili nel secondo commento su the forms_for API docs.