13

Dopo aver lavorato con ASP.Net MVC, ho pensato a Rails. Ho lavorato prima con Rails, ma sono un po 'arrugginito. Le esercitazioni di ASP.Net MVC consigliano di nascondere l'implementazione del livello dati con il modello di repository. Ciò consente l'iniezione delle dipendenze easiesr per i test unitari e il disaccoppiamento graduale del controller dall'implementazione del modello.Ruby on Rails con pattern di deposito?

Ricordo i controller di Rails che utilizzavano direttamente oggetti Active Record e test di unità usando database di test che potevano essere impostati e abbattuti con facilità. Ciò risolve la necessità di sostituire i test unitari, ma sembra comunque una cattiva idea avere così tanto codice ActiveRecord esposto nel controller.

Quindi la mia domanda è, qual è l'ultima best practice qui? I database reali (non presi in giro) sono ancora utilizzati per il test delle unità? Gli sviluppatori di Rails chiamano ActiveRecord direttamente o un'astrazione?

risposta

7

ActiveRecord costituisce davvero anche il "livello dati", mi chiedo? Dopotutto, il suo scopo è quello di astrarre (in misura abbastanza ragionevole) l'effettiva memoria di interazione. Se ho un modello che eredita da ActiveRecord::Base e faccio riferimento a quel modello in un controller, sto davvero interagendo con il livello dati?

Guardando una breve descrizione dello Repository Pattern, direi che i metodi dello find_by_ ti stanno già dando molto di ciò che descrive, che è buono, non è vero? OK, lo strato di astrazione perde (si potrebbe dire più genericamente "pragmatico") in quanto possiamo avvicinarci molto di più al metallo, se necessario, e ad esempio find_by_sql renderà evidente che abbiamo a che fare con un relazionale database di qualche tipo.

Non consiglierei mai (o forse dovrei dire "raramente e non senza giustificazioni estreme" - è sempre complicato usare absolutes) mettendo il codice nei controller che consente di dedurre la piattaforma di dati utilizzata. Dovrebbe essere inserito nei modelli: named_scope può essere molto utile qui. Per risultati complessi, considera l'utilizzo di oggetti "di presentazione" come l'interfaccia (Struct e il mio preferito personale OpenStruct può essere molto utile qui).

Mentre ActiveRecord è lo standard di fatto, dal momento che si installa con Rails, non è l'unico gioco in città. Per i database non SQL, qualcosa di diverso è necessario, ma anche nel dominio SQL c'è DataMapper (è che in base alla eponymous PoEAA pattern?)

In Rails 3.0 che sta per essere molto più facile per pick and choose components come l'ORM come Yehuda e i ragazzi disfano e puliscono le interfacce.

+0

sì 1000x costituisce un livello dati. non è abbastanza strettamente connesso all'uso di stringhe SQL specifiche del fornitore, ma le classi AR mappano 1 a 1 con le tabelle del database per la maggior parte. esso (e questo è vero per i binari in generale) incoraggia uno stile di programmazione in cui non vi è alcuna differenza tra gli oggetti di business e le tabelle di db. l'RP è specificamente progettato per fare questa distinzione. – Jonah

9

La mia esperienza è stata che Ruby on Rails integra ActiveRecord così strettamente (nella maggior parte dei casi può diventare quasi completamente trasparente) che gli sviluppatori spesso usano senza alcuna Astrazione.

La cosa da ricordare è che il pattern di repository e il pattern Active Record erano entrambi suggeriti in Patterns of Enterprise Architecture by Martin Fowler (che, se non l'hai ancora letto ... dovresti). Active Record è strettamente integrato in Rails. Microsoft .NET non ti lega a un pattern ... quindi il pattern di repository è stato adottato dalla maggior parte degli sviluppatori.

+0

Mi sono sempre chiesto se non volendo ActiveRecord, significa che Rails non è lo strumento per me. – SystematicFrank

+0

@SystematicFrank intendi ActiveRecord, la gemma Ruby OR ActiveRecord, il pattern. La maggior parte dei framework include ActiveRecord e sono strettamente integrati in essi. – iGbanam

0

Le convenzioni di Rotaie Folllowing portano sempre lungo il Sentiero dei ricordi meno dolorosi, quindi è consigliabile.

A seconda della definizione di "reale" ... Per il test delle unità, ho notato che le persone tendono a utilizzare lo stesso schema di dati del loro sito principale e sementi il ​​database prima dell'esecuzione dei test/durante i test (usando Factory Girl, Machinist o plain ol 'fixtures) e poi i test vengono eseguiti sulla base di quei dati.

Gli sviluppatori di Rails chiamano ActiveRecord direttamente su questi dati, come nel mondo reale.

0

I controllori devono accedere ai modelli in MVC. Rails cerca di evitare alcune delle astrazioni inutili che caratterizzano il mondo aziendale.

+0

Rails non è MVC, Rails è il modello 2. – siefca

+0

"Il modello 2 è un modello di progettazione complesso utilizzato nella progettazione di ** applicazioni Web Java ** che separa la visualizzazione del contenuto dalla logica utilizzata per ottenere e manipolare il contenuto." http://en.wikipedia.org/wiki/Model_2 –

+0

RoR è più vicino al modello 2 che a MVC. – siefca

2

Puoi farlo in entrambi i modi. Molto spesso, i test funzionali di Rails sono scritti per andare fino al database, dove i dati sono popolati da fixture, come descrivi.

Ma non è raro prendere in giro le chiamate di livello di servizio, ad esempio:

User.expects(:find_by_id).with("1").returns(u); 
get :show, :id=>"1" 

... o qualcosa del genere. In effetti, lo faccio sempre controllando l'oggetto del modello (o simulato anche quello).