web-dev-qa-db-fra.com

Meilleures pratiques pour la réutilisation du code entre les contrôleurs dans Ruby on Rails

J'ai quelques méthodes de contrôleur que j'aimerais partager. Quelle est la meilleure pratique pour ce faire dans Ruby on rails? Devrais-je créer une classe abstraite que mes contrôleurs étendent ou devrais-je créer un module et l'ajouter à chaque contrôleur? Vous trouverez ci-dessous les méthodes de contrôleur que je souhaite partager:

def driving_directions
  @address_to = params[:address_to]
  @address_from = params[:address_from]
  @map_center = params[:map_center_start]

  # if we were not given a center point to start our map on
  # let's create one.
  if !@map_center && @address_to
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll
  elsif !@map_center && @address_from
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll
  end
end

def printer_friendly
  starting_point = params[:starting_point].split(',').collect{|e|e.to_f}
  ne = params[:ne].split(',').collect{|e|e.to_f}
  sw = params[:sw].split(',').collect{|e|e.to_f}
  size = params[:size].split(',').collect{|e|e.to_f}
  address = params[:address]

  @markers = retrieve_points(ne,sw,size,false)
  @map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true)
  @address_string = address
end
79
Kyle Boon

À mon avis, les principes de conception OO normaux s'appliquent:

  • Si le code est vraiment un ensemble d'utilitaires qui n'ont pas besoin d'accéder à l'état d'objet, je considérerais de le placer dans un module pour qu'il soit appelé séparément. Par exemple, si le code concerne tous les utilitaires de mappage, créez un module Maps et accédez aux méthodes telles que: Maps::driving_directions.
  • Si le code nécessite un état et est utilisé ou peut être utilisé dans chaque contrôleur, placez-le dans ApplicationController.
  • Si le code nécessite un état et est utilisé dans un sous-ensemble de tous les contrôleurs étroitement liés logiquement (c'est-à-dire tout au sujet des cartes), créez une classe de base (class MapController < ApplicationController) et placez-y le code partagé.
  • Si le code nécessite un état et est utilisé dans un sous-ensemble de tous les contrôleurs peu liés, insérez-le dans un module et incluez-le dans les contrôleurs nécessaires.

Dans votre cas, les méthodes nécessitent un état (params), le choix dépend donc de la relation logique entre les contrôleurs qui en ont besoin .

Également:

  • Utilisez des partiels lorsque cela est possible pour le code répété et placez-les dans un répertoire commun, ou incluez-les via un chemin spécifique.
  • Si possible, utilisez une méthode RESTful (pour les méthodes). Si vous créez de nombreuses méthodes non RESTful, envisagez de les extraire vers leur propre contrôleur.
111
Ian Terrell

Je sais que cette question a été posée il y a 6 ans. Je veux juste souligner que dans Rails 4, il existe maintenant des problèmes de contrôleur qui constituent une solution plus prête à l'emploi.

31
Sam G

Je pense en fait qu'un module est le meilleur moyen de partager du code entre les contrôleurs. Les aides sont utiles si vous souhaitez partager du code entre différentes vues. Les helpers sont essentiellement des modules glorifiés. Par conséquent, si vous n'avez pas besoin d'un accès au niveau de la visualisation, je vous suggère de placer un module dans votre dossier lib.

Une fois le module créé, vous devez utiliser l'instruction include pour l'inclure dans les contrôleurs souhaités.

http://www.rubyist.net/~slagell/Ruby/modules.html

15
danpickett

si vous voulez partager des codes entre le contrôleur et les assistants, vous devriez alors essayer de créer un module dans la bibliothèque. Vous pouvez également utiliser @template et @controller pour accéder à la méthode dans le contrôleur et l’assistant . Consultez cette option pour plus de détails http://www.shanison.com/?p=305

1
Shanison

Je suis d'accord avec l'approche du module. Créez un fichier Ruby distinct dans votre répertoire lib et placez le module dans le nouveau fichier.

La méthode la plus évidente consiste à ajouter les méthodes à votre ApplicationController, mais je suis certain que vous le savez déjà.

1
Christoph Schiessl

J'ai trouvé qu'un moyen efficace de partager un code identique sur plusieurs contrôleurs consiste à faire hériter un contrôleur de l'autre (où réside le code). J'ai utilisé cette approche pour partager des méthodes identiques définies dans mes contrôleurs avec un autre ensemble de contrôleurs nommés.

0
Daniel Bonnell

Une autre possibilité:

Si votre code commun nécessite un état et que vous souhaitez partager le comportement entre les contrôleurs, vous pouvez le placer dans une ancienne classe Ruby ordinaire dans votre répertoire model ou lib. N'oubliez pas que les classes model ne doivent pas nécessairement être persistantes, même si toutes les classes ActiveRecord sont persistantes. En d’autres termes, il est acceptable d’avoir des classes transitoires model

0
Alan