Pourquoi tous les Active Record détestent? [fermé]

103

Au fur et à mesure que j'en apprends de plus en plus sur la POO et que je commence à implémenter divers modèles de conception, je reviens sans cesse à des cas où les gens détestent Active Record .

Souvent, les gens disent qu'il ne s'adapte pas bien (citant Twitter comme leur premier exemple) - mais personne n'explique en fait pourquoi il ne s'adapte pas bien; et / ou comment atteindre les avantages de la RA sans les inconvénients (via un modèle similaire mais différent?)

J'espère que cela ne se transformera pas en une guerre sainte sur les modèles de conception - tout ce que je veux savoir, c'est **** spécifiquement **** ce qui ne va pas avec Active Record.

S'il ne s'adapte pas bien, pourquoi pas?

Quels autres problèmes a-t-il?

Adam Tuttle
la source
9
Je suppose qu'en général, beaucoup de haine et d'aversion contre les modèles de conception sont liés à une mauvaise utilisation. Les gens ont tendance à en abuser et à les utiliser dans un mauvais contexte et se retrouvent avec une solution plus complexe que l'original
terjetyl
1
L'implémentation Active Record de Ruby ressemble plus à un ORM.
Jimmy T.
1
Il y a un phénomène social qui est pour obtenir une appréciation, une plus grande reconnaissance, semblent plus intelligents et tranchants, les gens ont tendance à répéter mécaniquement tout battage médiatique de la négation de toute norme actuelle, modèle, technologie largement adoptée, en le confondant avec le progrès révolutionnaire vers la prochaine vague.
Andre Figueiredo

Réponses:

90

Il y a ActiveRecord the Design Pattern et ActiveRecord la bibliothèque Rails ORM , et il y a aussi une tonne de contrefaçons pour .NET et d'autres langages.

Ce sont toutes des choses différentes. Ils suivent principalement ce modèle de conception, mais l'étendent et le modifient de nombreuses manières différentes, donc avant que quelqu'un ne dise "ActiveRecord Sucks", il doit être qualifié en disant "quel ActiveRecord, il y a des tas?"

Je ne connais que ActiveRecord de Rails, je vais essayer de répondre à toutes les plaintes qui ont été soulevées dans le cadre de son utilisation.

@BlaM

Le problème que je vois avec Active Records est qu'il ne s'agit toujours que d'une table

Code:

class Person
    belongs_to :company
end
people = Person.find(:all, :include => :company )

Cela génère du SQL avec LEFT JOIN companies on companies.id = person.company_idet génère automatiquement des objets Société associés afin que vous puissiez le faire people.first.companyet qu'il n'ait pas besoin d'accéder à la base de données car les données sont déjà présentes.

@ pix0r

Le problème inhérent à Active Record est que les requêtes de base de données sont automatiquement générées et exécutées pour remplir les objets et modifier les enregistrements de base de données

Code:

person = Person.find_by_sql("giant complicated sql query")

C'est déconseillé car c'est moche, mais pour les cas où vous avez simplement et simplement besoin d'écrire du SQL brut, c'est facile à faire.

@Tim Sullivan

... et vous sélectionnez plusieurs instances du modèle, vous faites essentiellement un "select * from ..."

Code:

people = Person.find(:all, :select=>'name, id')

Cela ne sélectionnera que les colonnes de nom et d'ID de la base de données, tous les autres «attributs» dans les objets mappés seront simplement nuls, à moins que vous ne rechargiez manuellement cet objet, et ainsi de suite.

Orion Edwards
la source
Puissant! Je ne connaissais pas cette particularité. Encore un autre argument pro-AR pour moi à mettre dans mon arsenal.
Tim Sullivan
Rejoindre va au-delà du modèle d'enregistrement actif.
Jimmy T.
"Person.find_by_sql" n'est pas du tout un modèle d'enregistrement actif. Son "enregistrement actif" m'a échoué, je dois donc le patcher manuellement.
magallanes
52

J'ai toujours trouvé qu'ActiveRecord est bon pour les applications rapides basées sur CRUD où le modèle est relativement plat (comme dans, pas beaucoup de hiérarchies de classes). Cependant, pour les applications avec des hiérarchies OO complexes, un DataMapper est probablement une meilleure solution. Alors qu'ActiveRecord suppose un rapport 1: 1 entre vos tables et vos objets de données, ce type de relation devient compliqué avec des domaines plus complexes. Dans son livre sur les modèles , Martin Fowler souligne qu'ActiveRecord a tendance à se décomposer dans des conditions où votre modèle est assez complexe, et suggère un DataMapper comme alternative.

J'ai trouvé que c'était vrai dans la pratique. Dans les cas où vous avez beaucoup d'héritage dans votre domaine, il est plus difficile de mapper l'héritage à votre SGBDR que de mapper les associations ou la composition.

La façon dont je le fais est d'avoir des objets "domaine" auxquels vos contrôleurs accèdent via ces classes DataMapper (ou "couche de service"). Ceux-ci ne reflètent pas directement la base de données, mais agissent comme votre représentation OO pour un objet du monde réel. Supposons que vous ayez une classe User dans votre domaine et que vous deviez avoir des références ou des collections d'autres objets déjà chargées lorsque vous récupérez cet objet User. Les données peuvent provenir de nombreuses tables différentes, et un modèle ActiveRecord peut rendre la tâche très difficile.

Au lieu de charger directement l'objet User et d'accéder aux données à l'aide d'une API de style ActiveRecord, votre code de contrôleur récupère un objet User en appelant l'API de la méthode UserMapper.getUser (), par exemple. C'est ce mappeur qui est chargé de charger tous les objets associés à partir de leurs tables respectives et de renvoyer l'objet "domaine" utilisateur terminé à l'appelant.

Essentiellement, vous ajoutez simplement une autre couche d'abstraction pour rendre le code plus gérable. Que vos classes DataMapper contiennent du SQL personnalisé brut, ou des appels à une API de couche d'abstraction de données, ou même qu'ils accèdent eux-mêmes à un modèle ActiveRecord, n'a pas vraiment d'importance pour le code du contrôleur qui reçoit un bel objet User rempli.

Bref, c'est comme ça que je fais.

Sam McAfee
la source
5
On dirait que vous n'êtes tout simplement pas familier avec ActiveRecord. "ActiveRecord suppose un rapport 1: 1 entre vos tables". Tout simplement pas vrai du tout. ActiveRecord a toutes sortes de magie relationnelle super impressionnante. Voir api.rubyonrails.org/classes/ActiveRecord/Associations/…
tybro0103
16
@ JoãoBragança - peut-être plutôt qu'un commentaire sarcastique, vous pourriez en fait expliquer les difficultés qui surviennent lorsque ses données sont fragmentées - afin que le reste d'entre nous puisse apprendre quelque chose :)
Taryn East
11

Je pense qu'il y a probablement un ensemble très différent de raisons entre pourquoi les gens «détestent» ActiveRecord et ce qui ne va pas avec lui.

En ce qui concerne la haine, il y a beaucoup de venin envers tout ce qui est lié à Rails. En ce qui concerne ce qui ne va pas, il est probable que ce soit comme toute technologie et il y a des situations où c'est un bon choix et des situations où il y a de meilleurs choix. La situation dans laquelle vous ne pouvez pas profiter de la plupart des fonctionnalités de Rails ActiveRecord, d'après mon expérience, est celle où la base de données est mal structurée. Si vous accédez à des données sans clés primaires, avec des éléments qui violent la première forme normale, où de nombreuses procédures stockées sont nécessaires pour accéder aux données, il vaut mieux utiliser quelque chose qui n'est plus qu'un simple wrapper SQL. Si votre base de données est relativement bien structurée, ActiveRecord vous permet d'en profiter.

Pour ajouter au thème de la réponse aux commentateurs qui disent que les choses sont difficiles dans ActiveRecord avec une réplique d'extrait de code

@Sam McAfee Supposons que vous ayez une classe User dans votre domaine et que vous deviez avoir des références ou des collections d'autres objets déjà chargées lorsque vous récupérez cet objet User. Les données peuvent provenir de nombreuses tables différentes, et un modèle ActiveRecord peut rendre la tâche très difficile.

user = User.find(id, :include => ["posts", "comments"])
first_post = user.posts.first
first_comment = user.comments.first

En utilisant l'option include, ActiveRecord vous permet de remplacer le comportement de chargement différé par défaut.

MattMcKnight
la source
8

Ma réponse longue et tardive, même pas complète, mais une bonne explication POURQUOI je déteste ce schéma, ces opinions et même certaines émotions:

1) version courte: Active Record crée une " fine couche " de " liaison forte " entre la base de données et le code de l'application. Ce qui ne résout aucun problème logique, aucun problème quelconque, aucun problème du tout. À mon humble avis, il ne fournit AUCUNE VALEUR, à l'exception du sucre syntaxique pour le programmeur (qui peut alors utiliser une «syntaxe d'objet» pour accéder à certaines données, qui existe dans une base de données relationnelle). L'effort pour créer un certain confort pour les programmeurs devrait (à mon humble avis) être mieux investi dans des outils d'accès aux bases de données de bas niveau, par exemple certaines variantes de simples, faciles, simpleshash_map get_record( string id_value, string table_name, string id_column_name="id" ) méthodes et similaires (bien sûr, les concepts et l'élégance varient considérablement avec le langue utilisée).

2) version longue: dans tous les projets basés sur des bases de données où j'avais le "contrôle conceptuel" des choses, j'évitais la RA, et c'était bien. Je construis généralement une architecture en couches (vous divisez tôt ou tard votre logiciel en couches, au moins dans les projets de taille moyenne à grande):

A1) la base de données elle-même, les tables, les relations, même un peu de logique si le SGBD le permet (MySQL est également développé maintenant)

A2) très souvent, il y a plus qu'un magasin de données: système de fichiers (les blobs dans la base de données ne sont pas toujours une bonne décision ...), systèmes hérités (imaginez "comment" ils seront accédés, de nombreuses variétés possibles .. mais c'est pas le point ...)

B) couche d'accès à la base de données (à ce niveau, les méthodes d'outils, les aides pour accéder facilement aux données de la base de données sont les bienvenues, mais AR ne fournit aucune valeur ici, sauf quelques sucres syntaxiques)

C) couche d'objets d'application: les «objets d'application» sont parfois de simples lignes d'une table dans la base de données, mais la plupart du temps, ils sont composés objets toute façon, et ont une logique plus élevée attachée, donc investir du temps dans des objets AR à ce niveau est tout simplement inutile , une perte de temps précieux pour les codeurs, car la "valeur réelle", la "logique supérieure" de ces objets doit être implémentée au-dessus des objets AR, de toute façon - avec et sans AR! Et, par exemple, pourquoi voudriez-vous avoir une abstraction des "objets d'entrée de journal"? Le code logique de l'application les écrit, mais cela devrait-il permettre de les mettre à jour ou de les supprimer? semble idiot, et certaines magnitudes sont plus faciles à utiliser . Et par exemple: l'utilisation d'un "objet Entrée de journal" dans la vue du journal de votre application fonctionnera pour 100, 1000 ou même 10000 lignes de journal, mais tôt ou tard, vous devrez optimiser - et je parie que dans la plupart des cas, vous n'aurez qu'à utilisez cette belle petite instruction SQL SELECT dans la logique de votre application (ce qui rompt totalement l'idée AR ...), au lieu d'encapsuler cette petite instruction dans des cadres d'idées AR fixes rigides avec beaucoup de code enveloppant et masquant. Le temps que vous avez perdu avec l'écriture et / ou la construction de code AR aurait pu être investi dans une interface beaucoup plus intelligente pour lire des listes d'entrées de journal (de nombreuses façons, le ciel est la limite).App::Log("I am a log message")le=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert();pour réaliser leur logique d'application qui correspond à l'application prévue, et ne pas réimplémenter bêtement des schémas idiots, ça sonne bien à première vue!

D) la logique de l'application - implémente la logique des objets en interaction et de la création, de la suppression et de la liste (!) Des objets de la logique de l'application (NON, ces tâches doivent rarement être ancrées dans les objets de la logique de l'application elle-même: la feuille de papier sur votre bureau le dit-elle vous les noms et les emplacements de toutes les autres feuilles de votre bureau? Oubliez les méthodes "statiques" pour lister les objets, c'est idiot, un mauvais compromis créé pour que la façon humaine de penser s'intègre dans [certains-not-all-AR-framework-like -] Pensée AR)

E) l'interface utilisateur - eh bien, ce que j'écrirai dans les lignes suivantes est très, très, très subjectif, mais d'après mon expérience, les projets qui reposaient sur la RA négligeaient souvent la partie UI d'une application - du temps était perdu à créer des abstractions obscures . En fin de compte, de telles applications ont fait perdre beaucoup de temps aux codeurs et se sentent comme des applications de codeurs pour codeurs, orientés vers la technologie à l'intérieur et à l'extérieur. Les codeurs se sentent bien (travail acharné enfin fait, tout est terminé et correct, selon le concept sur papier ...), et les clients "doivent juste apprendre que ça doit être comme ça", parce que c'est "professionnel" .. ok, désolé, je m'égare ;-)

Eh bien, certes, tout cela est subjectif, mais c'est mon expérience (Ruby on Rails exclu, cela peut être différent, et je n'ai aucune expérience pratique avec cette approche).

Dans les projets payants, j'ai souvent entendu la demande de commencer par créer des objets «enregistrement actif» comme élément constitutif de la logique d'application de niveau supérieur. Dans mon expérience, ce bien en évidence souventétait une sorte d'excuse pour que le client (une société de développement de logiciels dans la plupart des cas) n'ait pas un bon concept, une vue d'ensemble, un aperçu de ce que le produit devrait finalement être. Ces clients pensent dans des cadres rigides ("dans le projet il y a dix ans, ça a bien fonctionné .."), ils peuvent étoffer des entités, ils peuvent définir des relations d'entités, ils peuvent décomposer les relations de données et définir la logique de base de l'application, mais ensuite ils s'arrêtent et vous le remettez, et pensez que c'est tout ce dont vous avez besoin ... ils manquent souvent d'un concept complet de logique d'application, d'interface utilisateur, de convivialité, etc., ils n'ont pas la vue d'ensemble et ils manquent d'amour pour le détails, et ils veulent que vous suiviez cette façon de faire AR, parce que ... eh bien, pourquoi, cela a fonctionné dans ce projet il y a des années, cela garde les gens occupés et silencieux? Je ne sais pas. Mais les "détails" séparer les hommes des garçons, ou… comment était le slogan original de la publicité? ;-)

Après de nombreuses années (dix ans d'expérience dans le développement actif), chaque fois qu'un client mentionne un «modèle d'enregistrement actif», ma sonnette d'alarme sonne. J'ai appris à essayer de les ramener à cette phase de conception essentielle , de les laisser réfléchir à deux fois, de les essayer pour montrer leurs faiblesses conceptuelles ou simplement de les éviter du tout s'ils ne sont pas conscients (au final, vous savez, un client qui ne le fait pas encore) savoir ce qu'il veut, peut-être même pense qu'il sait mais ne le fait pas, ou essaie d'externaliser gratuitement le travail de concept vers MOI, me coûte beaucoup d'heures, de jours, de semaines et de mois précieux de mon temps, vivre est trop court ...).

Donc, enfin: CECI TOUT est la raison pour laquelle je déteste ce "modèle d'enregistrement actif" idiot, et je le fais et je l'éviterai autant que possible.

EDIT : J'appellerais même cela un No-Pattern. Cela ne résout aucun problème (les motifs ne sont pas destinés à créer du sucre syntaxique). Cela crée de nombreux problèmes: la racine de tous ses problèmes (mentionnés dans de nombreuses réponses ici ..) est qu'il cache juste le bon vieux SQL bien développé et puissant derrière une interface qui est par la définition des modèles extrêmement limitée.

Ce modèle remplace la flexibilité par du sucre syntaxique!

Pensez-y, quel problème la RA résout-elle pour vous?

Frunsi
la source
1
Il s'agit d'un modèle architectural de source de données. Peut-être devriez-vous lire les modèles d'architecture d'applications d'entreprise de Fowler? J'avais des pensées similaires aux vôtres avant d'utiliser réellement le modèle / ORM et de constater à quel point cela simplifiait les choses.
MattMcKnight
1
Je partage vos sentiments. Je sens quelque chose qui ne va pas quand un framework ne supporte pas les clés composées .... J'ai évité tout type d'ORM avant SQLAlchemy, et nous l'utilisons souvent à un niveau inférieur, comme générateur SQL. Il implémente Data Mapper et est très flexible.
Marco Mariani
1
Depuis deux jours je suis impliqué dans un projet qui utilise un ORM "à la pointe de la technologie", peut-être que les implémentations sont mûres maintenant (par rapport à ce avec quoi j'ai travaillé il y a quelques années). Peut-être que mon avis va changer, on verra dans trois mois :-)
Frunsi
2
Le projet est terminé, et vous savez quoi? ORM craint toujours, j'ai perdu tellement de temps avec des problèmes de mappage qui s'expriment facilement de manière relationnelle à un tas de "code orienté objet". Bien sûr, l'ORM fournissait des moyens d'exprimer des requêtes dans une sorte de POO + SQL-Mix - bien sûr dans une syntaxe de type POO - mais cela prenait juste plus de temps que la simple écriture d'une requête SQL. L'abstraction a fui, le "OOPSQLExperiment" au-dessus de la POO - permettre aux utilisateurs d'écrire du SQL en syntaxe POO était la pire idée qui soit. Non, plus jamais.
Frunsi
1
J'ai écrit du SQL brut pour tout pendant de nombreuses années. Rails AR me frustre parfois et pour les requêtes passives, je suis presque d'accord avec vous, mais c'est ce qu'il résout: 1) Rend convenablement difficile la sauvegarde des données qui échouent à la validation. 2) Suivi de ce qui a changé en mémoire depuis la dernière persistance. 3) Utilisation du point 2 pour écrire des before_saverappels sensibles afin de maintenir la cohérence dans l'enregistrement 4) after_commithooks pour les déclencheurs de service externes. 5) Un bon DSL pour organiser les changements DDL en changesets (migrations). (Il y a encore de la douleur là-bas, mais ne pas avoir de modèle est pire lorsque> 1 développeur.)
Adamantish
6

Certains messages me confondent. Certaines réponses vont à "ORM" vs "SQL" ou quelque chose comme ça.

Le fait est que la RA n'est qu'un modèle de programmation de simplification où vous tirez parti des objets de votre domaine pour y écrire le code d'accès à la base de données.

Ces objets ont généralement des attributs métier (propriétés du bean) et certains comportements (méthodes qui fonctionnent généralement sur ces propriétés).

L'AR dit simplement "ajouter des méthodes à ces objets de domaine" aux tâches liées à la base de données.

Et je dois dire, d'après mon opinion et mon expérience, que je n'aime pas le modèle.

À première vue, cela peut sembler plutôt bon. Certains outils Java modernes comme Spring Roo utilisent ce modèle.

Pour moi, le vrai problème est simplement la préoccupation de la POO. Le motif AR vous oblige d'une manière ou d'une autre à ajouter une dépendance de votre objet aux objets d'infra-structure. Ces objets d'infra-structure permettent à l'objet de domaine d'interroger la base de données via les méthodes suggérées par AR.

J'ai toujours dit que deux couches sont la clé du succès d'un projet. La couche de service (où réside la logique commerciale ou peut être exportée via une sorte de technologie de communication à distance, comme les services Web, par exemple) et la couche de domaine. À mon avis, si nous ajoutons des dépendances (pas vraiment nécessaires) aux objets de couche de domaine pour résoudre le modèle AR, nos objets de domaine seront plus difficiles à partager avec d'autres couches ou des applications externes (rares).

L'implémentation Spring Roo de AR est intéressante, car elle ne repose pas sur l'objet lui-même, mais sur certains fichiers AspectJ. Mais si par la suite vous ne souhaitez pas travailler avec Roo et devez refactoriser le projet, les méthodes AR seront implémentées directement dans vos objets de domaine.

Un autre point de vue. Imaginez que nous n'utilisons pas de base de données relationnelle pour stocker nos objets. Imaginez que l'application stocke nos objets de domaine dans une base de données NoSQL ou simplement dans des fichiers XML, par exemple. Allions-nous implémenter les méthodes qui effectuent ces tâches dans nos objets de domaine? Je ne pense pas (par exemple, dans le cas de XM, nous ajouterions des dépendances liées au XML à nos objets de domaine ... Vraiment triste je pense). Pourquoi alors devons-nous implémenter les méthodes DB relationnelles dans les objets du domaine, comme le dit le modèle Ar?

Pour résumer, le modèle AR peut sembler plus simple et bon pour les applications petites et simples. Mais, lorsque nous avons des applications complexes et volumineuses, je pense que l'architecture classique en couches est une meilleure approche.

Juanjo
la source
Bienvenue à SO. J'ai apprécié votre commentaire, mais cette question a été fermée comme non constructive par NullUserException le 17 décembre 2011 à 1:17
Tony Rad
3

La question concerne le modèle de conception Active Record. Pas un outil orm.

La question d'origine est étiquetée avec des rails et fait référence à Twitter qui est intégré à Ruby on Rails. Le framework ActiveRecord dans Rails est une implémentation du modèle de conception Active Record de Fowler.

John Topley
la source
2

La principale chose que j'ai vue en ce qui concerne les plaintes concernant Active Record est que lorsque vous créez un modèle autour d'une table et que vous sélectionnez plusieurs instances du modèle, vous faites essentiellement un "select * from ...". C'est très bien pour modifier un enregistrement ou afficher un enregistrement, mais si vous voulez, par exemple, afficher une liste des villes pour tous les contacts de votre base de données, vous pouvez faire "sélectionner la ville de ..." et obtenir uniquement les villes . Pour ce faire avec Active Record, vous devez sélectionner toutes les colonnes, mais uniquement en utilisant City.

Bien sûr, différentes implémentations géreront cela différemment. Néanmoins, c'est un problème.

Maintenant, vous pouvez contourner ce problème en créant un nouveau modèle pour la chose spécifique que vous essayez de faire, mais certaines personnes diront que c'est plus un effort que l'avantage.

Moi, je creuse Active Record. :-)

HTH

Tim Sullivan
la source
2
"Faire cela avec Active Record nécessiterait que vous sélectionniez toutes les colonnes, mais uniquement en utilisant City." Il est en fait extrêmement facile de spécifier une clause de sélection.
MattMcKnight
1

J'adore la façon dont SubSonic fait une seule colonne.
Soit

DataBaseTable.GetList(DataBaseTable.Columns.ColumnYouWant)

, ou:

Query q = DataBaseTable.CreateQuery()
               .WHERE(DataBaseTable.Columns.ColumnToFilterOn,value);
q.SelectList = DataBaseTable.Columns.ColumnYouWant;
q.Load();

Mais Linq est toujours roi en matière de chargement paresseux.

Lars Mæhlum
la source
1

@BlaM: Parfois, je viens de mettre en œuvre un enregistrement actif pour le résultat d'une jointure. Ne doit pas toujours être la relation Table <--> Active Record. Pourquoi pas "Résultat d'une instruction Join" <--> Enregistrement actif?

Johannes
la source
1

Je vais parler d'Active Record comme modèle de conception, je n'ai pas vu ROR.

Certains développeurs détestent Active Record, car ils lisent des livres intelligents sur l'écriture de code propre et soigné, et ces livres indiquent que l'enregistrement actif viole le principe de resposobility unique, viole la règle DDD selon laquelle l'objet de domaine doit être ignorant persistant, et de nombreuses autres règles de ce type de livres .

La deuxième chose que les objets de domaine dans Active Record ont tendance à être 1-to-1 avec la base de données, ce qui peut être considéré comme une limitation dans certains types de systèmes (n-tiers principalement).

C'est juste des choses abstraites, je n'ai pas vu ruby ​​on rails implémentation réelle de ce modèle.

Alex Burtsev
la source
0

Le problème que je vois avec Active Records est qu'il ne s'agit toujours que d' une table. Ce n'est pas grave, tant que vous ne travaillez vraiment qu'avec cette seule table, mais lorsque vous travaillez avec des données dans la plupart des cas, vous aurez une sorte de jointure quelque part.

Oui, la jointure est généralement pire que l' absence de jointure du tout en termes de performances, mais la jointure est généralement meilleure que la "fausse" jointure en lisant d'abord toute la table A, puis en utilisant les informations obtenues pour lire et filtrer la table B.

BlaM
la source
@BlaM: Vous avez absolument raison. Bien que je n'ai jamais utilisé Active Record, j'ai utilisé d'autres systèmes ORM boulonnés (en particulier NHibernate), et il y a deux gros reproches que j'ai: des façons stupides de créer des objets (c'est-à-dire des fichiers .hbm.xml, dont chacun obtient compilé dans leur propre assemblage) et le coup de performance encouru juste en chargeant des objets (NHibernate peut spike un processus monocœur pendant plusieurs secondes en exécutant une requête qui ne charge rien du tout, lorsqu'une requête SQL équivalente ne nécessite presque aucun traitement). Pas spécifique à Active Record bien sûr, mais je trouve que la plupart des systèmes ORM (et des systèmes de type ORM) semblent
TheSmurf
Il existe de nombreuses alternatives à l'utilisation des fichiers hbm.xml. Voir par exemple NHibernate.Mapping.Attributes et fluent-nhibernate.
Mauricio Scheffer le
À propos des performances de création d'objets, je n'ai jamais rencontré de tels problèmes de performance, vous voudrez peut-être vérifier avec un profileur.
Mauricio Scheffer le
@mausch: Pas besoin d'un profileur. C'est un problème assez connu. Je ne sais pas si cela s'applique à la dernière version (que je n'utilise pas encore dans mon travail). ayende.com/Blog/archive/2007/10/26/…
TheSmurf
4
L'utilisation de: joins ou: includes dans les recherches IE Customer.find (: all,: include =>: contacts,: conditions => "active = 1") effectuera une jointure SQL, et non une analyse complète de la table.
Tilendor
0

Le problème avec ActiveRecord est que les requêtes qu'il génère automatiquement pour vous peuvent entraîner des problèmes de performances.

Vous finissez par faire des astuces peu intuitives pour optimiser les requêtes qui vous laissent vous demander s'il aurait été plus efficace d'écrire la requête à la main en premier lieu.

engtech
la source
0

Bien que tous les autres commentaires concernant l'optimisation SQL soient certainement valides, ma principale plainte avec le modèle d'enregistrement actif est qu'il conduit généralement à une discordance d'impédance . J'aime garder mon domaine propre et correctement encapsulé, ce que le modèle d'enregistrement actif détruit généralement tout espoir de faire.

Kevin Pang
la source
ActiveRecord résout en fait le problème de discordance d'impédance en vous permettant de coder de manière OO par rapport à un schéma relationnel.
Mauricio Scheffer le
Voulez-vous élaborer? Le consensus général est que les objets modélisés d'après une base de données relationnelle ne sont, par définition, pas orientés objet (puisque les bases de données relationnelles ne tournent pas autour de concepts OO tels que l'héritage et le polymorphisme).
Kevin Pang le
Il existe trois méthodes connues pour mapper l'héritage à un schéma relationnel. Ref: castleproject.org/ActiveRecord/documentation/trunk/usersguide
Mauricio Scheffer
Je pense que vous confondez le projet Castle Active Record OSS avec Active Record le modèle de conception. La question initiale (et ma réponse) se réfèrent au modèle de conception. Le projet Castle Active Record contient des éléments pour aider au développement OO, mais le modèle lui-même ne le fait pas.
Kevin Pang le
Je citais juste Castle comme référence. ActiveRecord de RoR implémente l'héritage de table unique uniquement ( martinfowler.com/eaaCatalog/singleTableInheritance.html ), mais les autres stratégies sont à l'étude ( blog.zerosum.org/2007/2/16/… )
Mauricio Scheffer
0

Essayez de faire une relation polymorphe plusieurs à plusieurs. Pas si facile. Surtout lorsque vous n'utilisez pas d'ITS.

Alexandre Trauzzi
la source