2010-02-23 3 views
0

Je forme complexe semblable à un Ryan Bates screencast récentrails forme complexe et l'ordre avec la construction

Les éléments imbriqués fonctionnent très bien cependant. Je crée ou met à jour une grille de données telle que celle-ci à travers un formulaire où les prix du jour sont l'entrée. Mon problème commence quand ils laissent un vide. J'ai l'option nested_attributes_for pour ne pas enregistrer nils et cela fonctionne, si elles ne sauvegardent qu'une seule valeur dans une ligne particulière, elle sauvegarde le bon jour mais quand elle sera rechargée, elle le placera dans la mauvaise colonne. Je ne suis pas sûr comment commander les valeurs dans une rangée au formulaire. IE Une valeur enregistrée pour mercredi apparaîtra dans la colonne lundi (de la ligne correcte). Cela n'arrive pas si elles sauvegardent toute la valeur pour une rangée (alors cela fonctionne parfaitement).

Les données sont stockées dans la base de données comme si

ID OBJECT_ID DAYOFWEEK PRICE et l'affichage comme ci-dessous

+------+----------------+-------+-------+-------+------+-------+ 
| id | name   | Mon | Tue | Wed | Thu | Fri | -> +2 more days etc 
+------+----------------+-------+-------+-------+------+-------+ 
| 1234 | Some name  | 87.20 | 87.20 | 87.20 | 82.55| 85.48 | 
+------+----------------+-------+-------+-------+------+-------+ 
| 1234 | Some name  | 87.20 | 87.20 | 87.20 | 82.55| 85.48 | 
+------+----------------+-------+-------+-------+------+-------+ 
| 1234 | Some name  | 87.20 | 87.20 | 87.20 | 82.55| 85.48 | 
+------+----------------+-------+-------+-------+------+-------+ 

Le code du contrôleur soit bâtiment ou afficher ces valeurs est comme ceci:

contrôleur

@rooms.each do |r| 
    ((r.room_rates.size+1)..7).each { 
     r.room_rates.build 
    } 
end 

rooms.html.erb

<% @dow = 0 %> 
    <tr class="room"> 
<td><%= f.text_field :name %></td> 

<% f.fields_for :room_rates do |rates| %> 
    <%= render 'rates', :f => rates %> 

    <% @dow += 1 %> 
<% end %> 

<td class="delete_mode" style="display:none;"> 
    <%= f.hidden_field :_destroy %> 
    <%= link_to_function "remove", "remove_room(this)" %> 
</td> 
    </tr> 

rates.html.erb

<td> 
<%= f.text_field :price, :size => 3 %> 
<%= f.hidden_field :dayofweek, :value => @dow %> 
<%= f.hidden_field :source, :value => 0 %> 
</td> 

modèle room_rates (où les données de la forme va)

+-------+---------+-----------+-------+--------+---------------------------+---------------------------+ 
| id | room_id | dayofweek | price | source | created_at    | updated_at    | 
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+ 
| 92745 | 8  | 0   | 1.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92746 | 8  | 1   | 2.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92747 | 8  | 2   | 3.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92748 | 8  | 3   | 4.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92749 | 8  | 4   | 5.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92750 | 8  | 5   | 6.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92751 | 8  | 6   | 7.0 | 0  | 2010-02-23 14:33:05 +0100 | 2010-02-23 14:33:05 +0100 | 
| 92752 | 9  | 3   | 5.0 | 0  | 2010-02-23 14:33:33 +0100 | 2010-02-23 14:33:33 +0100 | 
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+ 

de commande dans la console

+---------+-----------+-------+--------+---------------------------+---------------------------+ 
| room_id | dayofweek | price | source | created_at    | updated_at    | 
+---------+-----------+-------+--------+---------------------------+---------------------------+ 
| 2517 | 0   |  |  |       |       | 
| 2517 | 1   |  |  |       |       | 
| 2517 | 2   | 3.0 | 0  | 2010-02-23 17:54:28 +0100 | 2010-02-23 17:54:28 +0100 | 
| 2517 | 3   | 4.0 | 0  | 2010-02-23 17:54:28 +0100 | 2010-02-23 17:54:28 +0100 | 
| 2517 | 4   |  |  |       |       | 
| 2517 | 5   |  |  |       |       | 
| 2517 | 6   |  |  |       |       | 
+---------+-----------+-------+--------+---------------------------+---------------------------+ 
+0

et/ou ... je pourrais s'il y a une sorte de validation qui pourrait être effectuée sur une ligne entière de données. Comment pourrais-je seulement accepter une ligne entière ou pas du tout? Je ne suis pas sûr de savoir comment faire cela avec 7 enregistrements distincts qui sont créés pour chaque ligne. – holden

Répondre

2

Le erreur est lorsque vous créez le formulaire - parce que vous dépendez de l'ordre o Pour que les room_rates soient corrects, vous devez placer les taux vides (construits) dans les positions correctes. Si chaque chambre dispose de nombreux tarifs, vous devez générer le formulaire afin que les tarifs soient au bon jour de la semaine. Ce code construire que dans un nouveau tableau, et réglé correctement le nouveau tableau:

@rooms.each do |r| 
    new_rates = [] 
    (0..6).each { |dow| 
    rate = r.room_rates.find_by_dayofweek(dow) 
    if rate 
     new_rates << rate 
    else 
     new_rates << r.room_rates.build(:dayofweek => dow) 
    end 
    } 
    r.room_rates = new_rates 
end 

Vous pouvez également être en mesure de construire juste les semaines manquantes, si vous spécifiez une commande pour votre association:

// In room model 
has_many :rates, :order => "dayofweek" 

// In controller 
@rooms.each do |r| 
    (0..6).each { |dow| 
    if not r.room_rates.find_by_dayofweek(dow) 
     r.room_rates.build(:dayofweek => dow) 
    end 
    } 
end 
+0

Désolé, j'aurais dû être plus clair, il n'y a pas de champs distincts dans l'enregistrement mais plusieurs enregistrements. J'ai ajouté le modèle des taux au bas de mon message. Cependant, la 2ème partie que vous avez ajouté pourrait fonctionner aussi. J'ai essayé des choses semblables mais il ne reçoit toujours pas la commande sur le formulaire correctement ;-( – holden

+1

J'ai édité ma réponse basée sur l'information supplémentaire dans la question – jamuraa

+0

Le premier semble que cela devrait fonctionner parfaitement. – holden

Questions connexes