2009-10-12 6 views
6

Sto sviluppando un sito Web Rails 2.3.1. In tutto il sito Web, ho bisogno di un modulo per la creazione di post su varie pagine (pagina iniziale, pagina Crea post, pagina di annuncio, pagina di elenco commenti, ecc. - basti dire che questo modulo deve trovarsi su molte pagine servite da una varietà di controller). Ciascuna di queste pagine visualizza un'ampia varietà di altre informazioni che vengono recuperate nel controller/azione corrispondente. Ex, la home page elenca gli ultimi 10 post, i contenuti estratti dal DB, ecc.Le migliori pratiche di Rails per avere lo stesso modulo su più pagine

Quindi, ho spostato il modulo di creazione del post in un suo partial e incluso questo parziale in tutte le pagine necessarie. Si noti che il modulo nei POST a/domande (che si dirige verso PostsController :: create - questo è il comportamento delle guide di default).

Il problema che sto incontrando è quando il modulo Post non è completato correttamente, per impostazione predefinita il PostsController :: crea il metodo di rendering questions/new.html.erb, anche se il modulo è stato inviato dalla home page (/ home/index.html.erb).

Ho provato a modificare il modulo nel parziale per inviare "submitting_controller" e "submitting_action", e in PostsController :: create, when @ post.save? == false, I render action => "../submitting_controller/submitting_action" (Che è leggermente hacky, ma ti permette di renderizzare le azioni da quelle di PostsController).

Questo sembrava funzionare correttamente in superficie. Il modulo incompleto è stato reso nella vista che lo ha inviato con tutto il messaggio @ post.errors corretto, ecc. Il problema era che TUTTI gli altri dati sulle pagine non si presentavano, perché i metodi effettivi submitting_controller/submitting_action non venivano chiamati, solo la vista associata. (Rieber, ho fatto un rendering che conserva gli oggetti di istanza, piuttosto che un redirect_to cui non conserva l'oggetto istanza @post che ha tutti i messaggi di errore e i valori inviati.)

Per quanto posso vedere ho due opzioni :

1) Posso archiviare l'oggetto @post nella sessione quando @ post.save? fallisce in PostsController :: create, redirect_to submitting_controller/submitting_action, a quel punto estraggo l'oggetto @post dalla sessione e lo uso per ri-popolare i messaggi di tipo/errore. (Per quanto ho capito, la memorizzazione degli oggetti nella sessione è pratica CATTIVA nei binari)

2) Posso spostare tutta la logica utilizzata per estrarre i dati del modulo di creazione non post dai vari submitting_controller/submitting_action, inserirli nel ApplicationController, crea una gigantesca istruzione switch in PostsController :: create per submitting_controller/submitting_action e chiama i metodi in ApplicationController per raccogliere tutti i dati extra necessari per ogni rendering della pagina di invio.

Pensieri sul modo migliore per farlo all'interno di Rails?

risposta

1

Per caso il tuo modello di posta in una proprietà appartiene a ogni modello che controller utilizzerai per rendere il tuo modulo? Stai facendo qualche elaborazione speciale nel controller Post oltre Post.create(params[:post])?

Se si è risposto sì alla prima domanda e no alla seconda, è possibile ottenere un minimo di manomissione aggiungendo accept_nested_attributes_for a ciascuno dei controller su cui un utente può creare un post.

Indipendentemente da ciò, Robertpostill ha ragione nel dire che questo è probabilmente il momento in cui iniziare a guardare AJAX, per sostituire solo la sezione della pagina. L'unico problema è cosa fare se un utente ha javascript disabilitato. Personalmente mi piace fare design per il caso non-javascript e aggiungere metodi di convenienza.

Per quanto riguarda i pensieri su quello che tu consideri le vostre due opzioni,

1) Ho usato questo metodo per memorizzare una copia di un oggetto nel hash flash. Preservandolo attraverso i reindirizzamenti. Tuttavia questo potrebbe non funzionare per te dato la natura variabile dei messaggi. Come si può inviare solo circa 4K valore di dati, e che include altre informazioni oltre alla tua copia superficiale.

2) Vedi di robertpostill risposta

+0

Emfi, Bel punto sugli attributi nidificati. Non mi era venuto in mente. Inoltre, il punto che si definisce in merito all'impostazione predefinita per non-JS è importante. Il sentimento che ho ottenuto è che l'interrogante (per mancanza di un handle migliore :) finirà per danneggiare le prestazioni dell'applicazione attraverso la quantità di azione DB che lui/lei avrebbe bisogno di eseguire ricostituendo tutti gli oggetti. – robertpostill

+0

Su questo siamo d'accordo. Tuttavia, la differenza tra non javascript e AJAX è solitamente una chiamata a link_to_remote, un RJS che rende un modello e probabilmente una piccola logica di controller per evitare le chiamate al database che normalmente si farebbero diversamente. – EmFi

+0

EmFi, Sfortunatamente il modello Post e i modelli di controller che utilizzerai per rendere il modulo potrebbero non essere correlati. (HomeController non ha nemmeno un modello di supporto). Faccio qualche controllo su un meccanismo captcha nel PostController :: create (il campo captcha non fa parte del Post Model, ma piuttosto un suo modulo). Penso che sia tu che Robertpostill abbiate ragione in AJAX sia il modo di affrontare questo problema.Devo solo capire come farlo con jQuery (ho deciso di non usare Prototype, pref personale) e non muckare nulla in Rails. – empire29

1

Questo è il punto in cui si passa da aggiornamenti a pagina intera a sezioni di aggiornamento di una pagina tramite l'uso di AJAX. Ci sono un sacco di cose che dovresti prendere in considerazione, ma l'approccio più strisciante sarebbe quello di dividere la risposta tra una risposta AJAX e una semplice risposta HTML. Controlla this ONLamp article, this register article o the awesome agile web development with rails book. Essenzialmente il controller esegue un nuovo div che sostituisce il vecchio div contenente il risultato dell'invio parziale.

Nella tua domanda si menziona due approcci e così cercherò di darvi alcune indicazioni su perché e perché non qui:

Opzione 1) opzione Ths non è così male con un paio di ritocchi. Il tweak principale è quello di memorizzare l'oggetto in una forma serializzata nel DB. Quindi passa semplicemente attorno all'ID dell'oggetto serializzato.I tuoi aspetti positivi sono che i dati della sessione vengono mantenuti, quindi il recupero di una sessione è più ordinato e la tua sessione rimane leggera. Il rovescio della medaglia di questo è che avere un secchio di sessione cruft nel tuo DB inquinerà la tua app e dovrai fare un po 'di riflessione su come scadere sessione inutilizzata dal database. Non ho mai visto questa fine bene ...

Option2) Eeek non all'interno del controller_applicativo! :) Seriamente, tienilo come arma di ultima istanza. Puoi comunque inserire le cose all'interno degli helper e accedere a questi metodi all'interno dei tuoi controller e visualizzazioni. Tuttavia, il test di quella roba non è così semplice, quindi fai attenzione prima di scegliere quella rotta. Le istruzioni switch possono essere sostituite in app OO con un po 'di riflessione, sicuramente nel suo caso è possibile utilizzare gli hash opzionali per ottenere un modo rudimentale di avere alcune informazioni sullo stato dell'applicazione al momento della richiesta.

+0

Grazie, Un paio di pensieri: opzione 1) objs inseguimento nel DB suona come potrebbe trasformarsi in un incubo, un pendio scivoloso davvero. Opzione 2) Non pensavo che i Controllori potessero accedere agli aiutanti (deve essere l'influenza di CakePHP). Sono d'accordo che ApplicationController è un posto lordo per metterli;) L'hash è una buona idea, anche se non mi piace ancora che tutta questa selezione di dati specifica per la vista venga trasferita in helpers - sembra proprio che potrebbe facilmente diventare un incubo di manutenzione. Leggerò gli articoli che hai fornito, ma penso che AJAX sarà la strada da percorrere. – empire29

Problemi correlati