2010-08-27 5 views
0

J'ai réussi à faire presque tout le chemin vers le bonheur avec ma forme personnalisée en ruby-on-rails, mais la toute dernière étape est manquante et il est impossible de trouver la réponse sur le net à cause de trop de mots communs.RoR: Comment gérer les formulaires personnalisés imbriqués soumettre

Je crois que les réponses à mes questions sont triviales pour les personnes qui ont fait RoR pendant un certain temps, mais soyez averti que la présentation de la question sera quelque peu compliquée.

Voyons un problème équivalent!

Schéma:

  • publishers (id, name, address)

  • books (id, title, publisher_id, publishing_year, unit_price, qty)

  • sell_log (id, user_id, timestamp, book_id, qty, unit_price, comment)

action personnalisée:

  • Nom: Vendre (contexte: un livre)

  • Entrée: qty, comment, (entrée implicite: book.id, timestamp; entrée dérivées: user_id, , book.qty)

  • résultat:

    • sell_log est ajouté

    • books.qty diminué

  • erreurs possibles:

    • La quantité est non-positive ou non-entière.

    • Le qté à l'entrée de l'utilisateur est supérieure à la qté disponible (book.qty)

(Pour votre information: Il est une question sur la conception de base de données.)

donc nous avons un formulaire personnalisé (caché book-id; qty, comment) que nous voulons implémenter comme une action dans un comportement similaire à "Edit" d'un livre (update). Qu'est-ce qui est fait (est presque tout):

- books_controller.rb: Ajouté colonne custom_qty_display.

- books_helper.rb:

def custom_qty_display_column(record) 
    record.qty.to_label + " [" 
    link_to("Sell..." \ 
      , { :controller => "books", :action => "sell_form", :id => record.id, :page => false } \ 
      , { :position => "replace", :inline => true, :class => "action" } \ 
     ) \ 
    + "]" 
end 

- vues/livres/sell_form.erb (seulement les principaux détails)

<% 
    form_remote_tag(\ 
    :url => { :controller => :books, :action => :sell, :id => params[:id] } \ 
) do 
%> 
... 
<%= submit_tag 'Submit' %> 
<%= link_to as_(:cancel), main_path_to_return, :class => 'cancel' %> 
<% end %> 
<div id="as_books-messages" class="messages-container" /> 

- books_controller.rb:

def sell 
    errors = [] # We will collect error messages here 
    # Checking parameters ... 
    # Checking of available qty ... 
    # If "errors" is still empty here, perform the action 
    # Produce the output according to the above: 
    if request.xhr? 
    if errors.empty? 
     # Q1: rendering of javascript which replaces the form with the modified row in the table. 
    else 
     # Q2: rendering of javascript which provides the "errors" for the user 
    end 
    else 
    if errors.empty? 
     index 
    else 
     # Q3: Redisplay the form and errors 
    end 
    end 
end 

Les progrès actuels

Lorsque je clique sur le lien "Vendre ..." à une entrée liste de livres l'entrée disparaît, le formulaire personnalisé apparaît à la place. Sur le formulaire, le lien "Annuler" (et le bouton [X]) fonctionne parfaitement; le bouton SOUMETTRE fonctionne (l'action est terminée avec succès lorsque l'entrée est correcte).

Ce qui n'est pas là, c'est que la forme reste en place. En théorie, je devrais retourner le javascript approprié sur les lieux marqués avec Q1, Q2 et Q3. Je ne veux pas désosser les choses et écrire les javascripts avec la main car sur une mise à jour du framework je serais obligé de refaire cette étape. Je veux produire les javascripts nécessaires de la meilleure manière possible en ce qui concerne la simplicité et la maintenabilité. Comme je le crois maintenant, mon concept n'est pas mauvais.

information Version

  • JRuby 1.5.0
  • gemmes
    • rails
    • 2.3.4 activerecord
    • 2.3.4 ActiveSupport
    2.3.4

(Dites-moi si autre chose nécessaire)

Résultat partiel

# ... 
if errors.empty? 
    render :action => 'on_update.js' 
else 
    # ... 
end 
# ... 
+0

ARGH ... Vous avez manqué le point dans la question. Terminer quand même, parce que c'était une lutte d'une semaine avec les forces. Ce sera précieux pour l'univers (j'espère). Voir le journal d'édition – Notinlist

Répondre

0

Étape # 1: Vous devez modifier le link_to dans votre aide pour inclure eid

link_to("Close..." \ 
    , { :controller => "books", :action => "sell_form", :id => record.id, :page => false, :eid => @controller.params[:eid] } \ 
    , { :position => "replace", :inline => true, :class => "action" } \ 
) 

Étape # 2: Vous devez modifier le sell_form.erb et mettre parent_model, parent_column, nested et eid dans le url. Vous devez définir update à book_list et vous devez générer un ID HTML approprié pour le formulaire avec element_from_id().

<% 
    form_remote_tag(\ 
    :url => { :controller => :books, :action => :sell, :id => params[:id], :parent_column => "books", :parent_model => "Publisher", :nested => "true", :eid => params[:eid] } \ 
    , :update => :book_list \ 
    , :html => { :id => element_form_id(:action => :update) } \ 
) do 
%> 

Étape # 3: Modifier la partie if request.xhr? au code simple suivant. (Pas entièrement testé, le meilleur cas fonctionne correctement.)

if request.xhr? 
    if @record.valid? 
    render :action => 'on_update.js' 
    else 
    render :action => 'form_messages.js' 
    end 
else 
    if @record.valid? 
    return_to_main 
    else 
    render :action => 'sell_form' 
    end 
end 
1

qui Rails version est l'application à l'aide? Quelle bibliothèque javascript utilise l'application? Les ressources RESTful de Book et SellLog?

Est-ce la raison pour laquelle vous n'utilisez pas link_to_remote dans les blocs d'aide et respond_to dans les actions du contrôleur?

Avec Rails 2.3 à l'aide de prototype je le fais comme ceci:

in controller: 

def sell 
    # … 
    # book/quantity/errors 
    # … 
    respond_to do |format| 
    if errors.empty? 
     format.js {render :update do |page| 
     page.replace_html '_ID_OF_DOM_OBJECT_CONTAINING_ROW_INFO_', :partial => '_PARTIAL_FOR_ROW_INFO_LAYOUT_' 
     end} 
     format.html { redirect_to :action => _WHATEVER_THE_SUCCESS_ACTION_IS_ } 
    else 
     format.js {render :update do |page| 
     page.replace_html 'form', :partial => '_DOM_ID_OF_FORM_' 
     end} 
     format.html { render :action => _WHATEVER_ACTION_DISPLAYED_THE_FORM_ } 
    end 
    end 
end 

_PARTIAL_FOR_ROW_INFO_LAYOUT_ aurait:

<div id="_ID_OF_DOM_OBJECT_CONTAINING_ROW_INFO_"> 
    <!-- row display markup --> 
</div> 

Beaucoup de ce que vous faites serait plus facile en suivant les conventions Rails, mais je ne connais pas votre version de Rails, l'application DSL, ni les plugins et/ou gemmes utilisés par votre application qui pourraient expliquer le motif courant dans votre contrôleur.

+0

J'ai ajouté des informations de version à la fin de ma question. '_PARTIAL_FOR_ROW_INFO_LAYOUT_' devrait avoir un moyen trivial de rendre. Si je débogue la réponse d'une action "Edit" ('update') réussie, je vois des tonnes de javascript. J'espérais que quelqu'un connaisse les quelques lignes nécessaires pour les générer. Je continue à creuser, afficherai mes propres résultats quand je l'ai. Presque oublié! Votre réponse enseigne encore beaucoup! Merci :-) – Notinlist

Questions connexes