J'ai une application qui modélise une maison. The House Has_Many Chambres, chambres haussières lumières et petites_appliances, etc. Je dispose également d'un contrôleur appelé Calculator, comment l'application est accessible. Les données sont ajoutées à la maison (et à ses chambres) à l'aide du contrôleur de calculatrice. Ensuite, un rapport est généré, situé à l'application / vues / calculatrice / reporter.html.erb.
Ma question est où tous les calculs et la logique du rapport sont-ils? Actuellement, j'ai tout dans la vue, avec certaines choses dans la calculatrice_Helper. Normalement, cela irait dans le modèle, non? Mais la calculatrice n'a pas de modèle généré. Quelle est la norme pour cela? P>
Voici le contrôleur de calculatrice. P>
class CalculatorController < ApplicationController def index end def save_house @house = House.new(params[:house]) respond_to do |format| if @house.save format.html { render :action => 'add_rooms', :id => @house } format.xml { render :xml => @house, :status => :created, :location => @house } else format.html { render :action => 'index' } format.xml { render :xml => @house.errors, :status => :unprocessable_entity } end end end def add_rooms @house = House.find(params[:id]) @rooms = Room.find_by_house_id(@house.id) rescue ActiveRecord::RecordNotFound logger.error("Attempt to access invalid house #{params[:id]}") flash[:notice] = "You must create a house before adding rooms" redirect_to :action => 'index' end def add_room @room = Room.new(params[:room]) @house = @room.house respond_to do |format| if @room.save flash[:notice] = "Room \"#{@room.name}\" was successfully added." format.html { render :action => 'add_rooms' } format.xml { render :xml => @room, :status => :created, :location => @room } else format.html { render :action => 'add_rooms' } format.xml { render :xml => @room.errors, :status => :unprocessable_entity } end end rescue ActiveRecord::RecordNotFound logger.error("Attempt to access invalid house #{params[:id]}") flash[:notice] = "You must create a house before adding a room" redirect_to :action => 'index' end def report flash[:notice] = nil @house = House.find(params[:id]) @rooms = Room.find_by_house_id(@house.id) rescue ActiveRecord::RecordNotFound logger.error("Attempt to access invalid house #{params[:id]}") flash[:notice] = "You must create a house before generating a report" redirect_to :action => 'index' end end
4 Réponses :
Tout cela dépend du type de données que vous créez. À quoi ressemble le contrôleur de calculatrice? p>
Vous pouvez créer vos propres classes dans / lib et les utiliser dans vos modèles, ce qui peut être un bon moyen de séparer la logique du contrôleur / des aides. Y a-t-il une raison pour laquelle vous ne pouviez pas mettre une partie de la logique dans les modèles? p>
Calculator_Controller enregistre les données et déplace l'utilisateur à la page suivante qui leur permet de saisir plus d'informations. Les modèles font validation, mais c'est à ce sujet. Les calculs en cours d'exécution sont principalement des calculs de nombre basés sur des paramètres de la maison et de la pièce. J'ai essayé de faire un modèle pour la calculatrice, mais je ne peux pas accéder aux variables de la vue. Devrais-je faire alors toutes les variables mondiales?
Je créerais une classe dans rails_root / lib / appelé, par exemple, calculatrice et placez le code là-bas. p>
Les classes in / lib / doivent être chargées une disponibilité disponible dans votre application. P>
Vous pouvez également créer un objet plain-rubis dans / app / des modèles /. Il n'y a aucune raison pour laquelle ils doivent tous hériter de Activerecord :: base p>
J'ai fait un fichier Calculator.rb dans l'application / des modèles qui ne héritent pas d'activerecord. Cependant, lorsque je déplace mon code dans ce fichier, je ne peux plus y accéder à partir de la vue. Je suppose que c'est parce que je l'ai fait avec des variables locales. Quelle est la meilleure façon de résoudre ce problème? J'ai essayé de les changer à des variables globales, mais cela ne semble pas aider.
Mettre les méthodes dans les modèles, au lieu d'une classe dans LIB /, vaut mieux lier la logique aux données sous-jacentes. En outre, il a l'avantage distinct de ne pas souffrir de ce problème concernant les variables d'instance, car vous pouvez appeler les méthodes sur les instances des modèles que vous gérez déjà dans le contrôleur et les vues. Code de l'agriculture dans la lib / constitue le plus de sens si elle est utilisée par plusieurs classes de votre codeBase, telles qu'un module de mixin, ou si vous refactez quelque chose dans un projet / plugin de Sidecar réutilisable. Si la logique fait partie du codeBase, conservez-le avec votre code principal.
Il y a quelques façons de l'approcher, mais la logique n'appartient certainement pas à la vue. Vous avez les différents modèles associés aux autres dans une hiérarchie claire avec le haut de la hiérarchie étant le modèle de la maison, si je lis votre description correctement. Cela étant le cas, j'ajouterais une méthode appropriée d'ensemble des méthodes du modèle de la maison pouvant être composé d'appels aux méthodes de calcul dans les modèles de la pièce associés à une instance de maison donnée et sur la ligne d'association. De cette manière que le calcul pertinent peut être effectué à chaque niveau et en composant une ou plusieurs méthodes au niveau du modèle de la maison, vous pouvez avoir une manière propre, expressive et maintenable de traiter les calculs. P>
Une chose à faire, aussi, serait de s'assurer que tous les calculs pouvant être effectués par la DB sont. Par exemple, s'il y a un calcul qu'un modèle de chambre peut effectuer simplement en interrogeant ses propres données, alors à tous les moyens, poussez ce fardeau informatique à la DB à l'aide de la capacité d'ActiveRecord à apposer une logique de calcul de ce niveau inférieur. Découvrez le API Docs pour les détails. P>
J'irais très soigneusement la logique que vous souhaitez et voyez comment il peut être poussé dans le modèle car c'est probablement là où il appartient, près des données réelles des calculs et dans les structures de classe qui représentent ces données spécifiquement ; Je ne créerais pas de modèle juste pour gérer la logique de calcul que si vous n'avez pas besoin de stocker les calculs de manière persistante pour une raison quelconque. P>
OK, maintenant je peux voir le code posté. Je peux voir que la calculatrice_controller n'a actuellement aucun calcul, sont-ils dans la vue? Essayez cette approche:
mon réponse préalable: p>
Si la logique commerciale est assez simple et utilisée uniquement derrière cette application Web, vous pouvez la mettre dans votre dossier App / Models. P> xxx pré>
puis dans votre contrôleur, créez une instance de votre modèle p> puis dans vos modèles, vous pouvez y accéder p> <%=h @mcc.calculate_coolness %>
J'aime construire des modèles comme celui-ci lorsque la logique commence à encombrer le modèle AR.
S'il vous plaît montrez-nous votre classe de calculatrice.
J'aime la réponse de James. Une autre question que je pense que vous devriez vous demander est de vous demander la raison de la convention - pourquoi le contrôleur de calcul est-il manipulant des choses qui appartiennent apparemment au contrôleur de la maison? Je ne dis pas que tu le fais mal, je dis simplement que ça vaut la peine de penser plus de réflexion.
Bon point, Andy. Ryan, obtenez les modèles juste avant de commencer à vous inquiéter des contrôleurs et des vues. En utilisant cette approche, vous pouvez découvrir que le bon endroit pour tous les calculs est le modèle de la maison.
J'ai ajouté le contrôleur de calculateur au poste d'origine. Le placement de tout n'a été mis en place par moi. Je poursuis ce projet. Cependant, je peux déplacer des choses si besoin d'être. Je vais devoir y penser. La maison peut très bien être le meilleur endroit pour les calculs. Je ne voudrais pas non plus que l'URL de l'application soit Site.com/Houses. Site.com/Calculator est meilleur.
Je regarderais cela comme un refacteur alors. Ne persistisez pas le maintien du code dans le mauvais, ou du moins dans un mauvais chemin. Identifiez l'endroit où la logique appartient et le réalise en permanence, espérons-le.