2010-10-09 3 views
9

Disons que nous avons une méthode dans un modèle quiUne méthode de modèle devrait-elle appeler 'save' elle-même?

  1. a besoin d'appeler uniquement sur les enregistrements sauvegardés
  2. peut mettre à jour le modèle lui-même et donc le modèle doit être enregistré à nouveau postfaces

Les appels "save" doivent-ils se produire à l'intérieur de la méthode elle-même, comme le code suivant

def result 
    save! if new_record? 

    # do some funky stuff here that may also change the model state 
    # ... 
    # And calculate the return value 
    search_result = "foo" # Let's say "foo" is the value we calculated 

    save! if changed? 
    search_result # return 
end 

Ou l'observateur externe (e e contrôleur) être responsable de l'appel en cas de besoin?

+0

En quelque sorte question connexe: http://stackoverflow.com/questions/3125198/should-a-modifying-class-method-save-itself-or-be-explicity-called-after-the-meth –

+0

Cette présentation sur Le test pourrait être en mesure de vous aider à déterminer où l'interface de ce modèle devient bizarre. https://github.com/jimweirich/presentation_testing_why_dont_we_do_it_like_this/raw/master/pdf/testing.key.pdf Si vous avez l'impression que vous devez appuyer sur la touche db lorsque vous testez votre application, il y a probablement des fonctionnalités qui peuvent être factorisé qui rendra l'architecture plus facile à utiliser. Commencez autour de pg. 69. –

+0

Je ne sais pas comment il se rapporte réellement à la question mais excellente présentation néanmoins - merci pour le partage! –

Répondre

4

Si votre méthode a vraiment, vraiment besoin de faire tout cela, soit.

Cependant, je tiens à préciser de regarder la méthode pourquoi vous faites que (les commentaires pourraient être bien ici), et je certainement faire une bang_method! afin qu'il soit clair pour celui qui l'invoque que cette méthode est susceptible de jouer avec l'objet autant qu'il aime.

En outre, le nom de la méthode result (qui, je sais, n'est probablement pas le vrai nom de votre méthode) implique en quelque sorte que vous ne faites que récupérer des données, et un peu plus. Peut-être que load_result! serait plus approprié ici, pour clarifier le fait que vous n'accédez pas simplement à un attribut, mais effectuez en fait des opérations lourdes pour l'obtenir.

2

Quand un programme enregistre-t-il des données sur un fichier?

a) Seulement lorsque l'utilisateur l'exige (directement ou indirectement)? - ceci est un cas de contrôleur

b) Seulement lorsque le programme atteint une partie de son exactitude et de l'intégrité des données? - c'est le cas modèle

c) Les deux.

Je voterais pour (c). J'espère que cette discrimination redresse un peu les choses.

De plus, du point de vue de la conception orientée objet, la méthode save() appartient au contrat public de sa classe; il peut être invoqué par n'importe qui. Compte tenu de cela, une classe est responsable de son contrat public et, si nécessaire, un objet peut invoquer ses propres méthodes à volonté.

4

Il y a définitivement des moments où un modèle doit persister. Mais il vaut la peine de considérer si enregistrer est la meilleure méthode pour votre application. Dans un exemple actuel, nous avons un modèle qui traite un fichier de manière asynchrone dans une méthode de longue durée (nous désactivons le processus à l'aide de sidekiq). Dans la méthode, un attribut persistant est régulièrement mis à jour disponible pour d'autres demandes.

Nous utilisons update_column plutôt que sauver, car

  1. Nous ne voulons pas ou ont besoin les frais généraux des callbacks AR, et nous voulons surtout ignorer la validation pour assurer la mise à jour se produit sûrement et immédiatement.
  2. Nous avons seulement besoin de mettre à jour un seul attribut. L'utilisation update_column évite la nécessité de déterminer si d'autres attributs doivent être sauvegardés (ou non enregistré.)

A l'intérieur du modèle, des méthodes telles que

  • update_column
  • save (: validate => false)(accordé, même méthode, mais différentes options)
  • contact

etc, peut souvent être un moyen de maintenir plus approprié des changements qu'un simple sauver.

Questions connexes