Skip to content

a Ruby kata to implement some famous ActiveRecord methods on PORO

Notifications You must be signed in to change notification settings

ParisRubyWorkshop/ActiveRecord_like

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 

Repository files navigation

Un problème très simple (dans son énoncé !) ou

comment faire duraille (oui, j'ai honte !) sans Rails !

imaginez que vous travaillez avec des PORO (Plain Old Ruby Object) comme ceci :

class Car
end
class Bicycle
end

Le but du kata est de mimer le comportement d'ActiveRecord sur plusieurs points:

  • créer une méthode :id qui permette, pour chaque nouvel objet instancié à partir de ces classes de lui donner un id unique
  • Un peu plus dur: créer une méthode :find telle qu'on puisse l'utiliser ainsi :
class Car
  def initialize(super_arguments_super_utiles_ou_rien)
    # ...
  end
# ...
end

class Bicycle
  def initialize(super_arguments_super_utiles_ou_rien)
    # ...
  end
  # ...
end
first_car = Car.new(super_arguments_super_utiles_ou_rien)
second_car = Car.new(super_arguments_super_utiles_ou_rien)
third_car = Car.new(super_arguments_super_utiles_ou_rien)
first_car.id #=> 1
third_car.id #=> 3

Car.find(id: 3) #=> #<Car:0x0000000003bbd458 @id=3>
# ou
Bicycle.find(id: 2)

Bien entendu, si vous-même ou l'un des membres de votre équipe était capturé, le Département d'Etat nierait toute implication on fait du Canada- DRY (ouh-là là je suis en forme dis-donc !), donc pas question de définir ces 2 méthodes dans chaque classe, on ne les définit qu'une seule fois, par exemple dans un (ou 2 ! spoiler...) module(s) que vous importerez de la bonne manière, pour avoir une méthode d'instance (:id) ou une méthode de classe (:find)

Une bonne adresse pour faire connaissance avec les joies de la métaprogrammation, ou encore. Sinon, le livre "Metaprogramming Ruby 2" de Paolo Perrotta est une mine d'or sur Ruby, pour bien comprendre ce langage, illustré de très nombreux exemples de "vrai" code tiré des Gems les plus connues (dont Rails).
Une excellente référence, pour celles et ceux qui ne connaissent pas cette oeuvre et maîtrisent l'anglais, le "Why's (Poignant) guide to Ruby"

Si vous séchez, A ne lire qu'après avoir cherché pendant au moins 5 heures :-)
* pour commencer, vous pouvez coder ces méthodes directement dans la classe Car, on verra après pour les mettre dans des modules  
* il y a plusieurs façons de procéder, mais commencez avec des variables de classe (mais si vous connaissez, 
 les @@nom_variable)
* Maintenant, refactorisez en [virant les variables de classes](https://kakesa.net/blog/ruby-pourquoi-eviter-les-variables-de-classes/)
pour les ids, en les remplaçant par des variables d'instance de classe (ben oui, puisque les classes sont aussi des
objets, elles peuvent avoir leur variable d'instance (de class)
* pour la méthode `Car.all` demandez à votre oracle préféré comment connaître toutes les instances d'une classe OU 
consulter la [doc](https://ruby-doc.org/core-2.6.5/ObjectSpace.html), vu qu'il n'y a que 6 méthodes, trouver la bonne 
ne devrait pas être trop dur !
* YAPUKA extraire toutes vos belles méthodes pour les mettre dans des modules, un pour les méthodes d'instances, un 
autre pour celles de classe et de les importer correctement grâce à **2** méthodes, une pour chacun des modules, que 
vous trouverez [ici](https://ruby-doc.org/core-2.6.5/Module.html)
  • Bon, ça c'est fait, alors on continue à faire du ActiveRecord like, maintenant vous allez implémentez les dynamic finders
class Car
  def initialize(super_arguments_super_utiles_ou_rien)
    # ...
  end

  def motor
    %w(diesel gazoline electric).sample
    # ...
  end
# ...
end

first_car = Car.new(super_arguments_super_utiles_ou_rien)
second_car = Car.new(super_arguments_super_utiles_ou_rien)
third_car = Car.new(super_arguments_super_utiles_ou_rien)


Car.find_by_motor('diesel') #=> [#<Car:0x0000000003bbd458 @id=3>]

Pour simplifier, on considérera que toutes les méthodes d'instance concernent des attributs, par exemple on n'aura pas ce genre de méthode

class Bicycle
  # ... genre de méthode q'il n'y aura PAS
  def calcul_developpement(rayon_roue, nb_pignons_roue, nb_pignons_pedalier)
  end 
end
end

Bien entendu, vous ne devez pas coder en dur ces méthodes de recherche, elles doivent etre créer dynamiquement !

Si vous séchez, A ne lire qu'après avoir cherché pendant au moins 5 heures (ce qui fait déjà 10 heures!) :-)
Pour ce faire vous allez avoir besoin de :
* tout d'abord, il vous faut retrouver les méthodes définies sur chaque classe. Heureusement votre meilleur ami est 
(toujours) là pour vous aider : la [doc officielle de Ruby](https://ruby-doc.org/core-2.6.5/Module.html) ! A vous de 
regarder quelle méthode ferait cela.  
* maintenant qu'on a les noms des méthodes d'instances, on va itérer dessus, en définissant dynamiquement. Des méthodes
comme `Module#class_eval`, `Module#define_method`, ou `Object#define_singleton_method` et `Object#send` peuvent vous         être utiles (ou pas, suivant votre implémentation !)

About

a Ruby kata to implement some famous ActiveRecord methods on PORO

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published