Mettre la logique de présentation dans le contrôleur est une bonne pratique dans Ruby ?
-
12-12-2019 - |
Question
Certaines recommandations [1] vous suggèrent d'utiliser
<%= current_user.welcome_message %>
au lieu de
<% if current_user.admin? %>
<%= current_user.admin_welcome_message %>
<% else %>
<%= current_user.user_welcome_message %>
<% end %>
Mais le problème est que vous devez avoir la logique de décision quelque part dans votre code.
Je crois comprendre que la décision est prise template
est mieux que controller
car cela rend votre contrôleur plus propre.Est-ce correct?
Existe-t-il une meilleure façon de gérer cela ?
La solution
À mon avis, si le texte est la seule chose qui change, elle n'appartient pas à une vue.Si vous aviez besoin de restructurer la page, c'est la logique de présentation.Ceci, ce n'est que des données étant différentes.
Autres conseils
Vous n'êtes pas le premier à vous poser cette question.Si les vues et les contrôleurs doivent avoir peu ou pas de logique et que le modèle doit être indépendant de la présentation, quelle est la place de la logique de présentation ?
Il s'avère que nous pouvons utiliser une vieille technique appelée modèle de décorateur.L'idée est d'envelopper votre objet modèle avec une autre classe contenant votre logique de présentation.Cette classe wrapper est appelée décorateur.Le décorateur éloigne la logique de votre vision, tout en gardant vos modèles isolés de leur présentation.
Drapier est un excellent joyau qui aide à définir les décorateurs.
L'exemple de code que vous avez donné pourrait être résumé comme suit :
Passez un décorateur à la vue avec @user = UserDecorator.new current_user
dans votre contrôleur.
Votre décorateur pourrait ressembler à celui ci-dessous.
class UserDecorator
decorates :user
def welcome_message
if user.admin?
"Welcome back, boss"
else
"Welcome, #{user.first_name}"
end
end
end
Et votre point de vue contiendrait simplement @user.welcome_message
Notez que le modèle lui-même ne contient pas la logique permettant de créer les messages.Au lieu de cela, le décorateur enveloppe le modèle et traduit les données du modèle sous une forme présentable.
J'espère que cela t'aides!
J'utiliserais une aide pour cela.Supposons que vous deviez traduire le message de bienvenue en fonction de paramètres régionaux.
Dans le app/helper/user_helper.rb
écrire
module UserHelper
def welcome_message(user)
if user.admin?
I18n.t("admin_welcome_message", :name => user.name)
else
I18n.t("user_welcome_message", :name => user.name)
end
end
end
et à votre avis, vous pouvez alors simplement écrire
<%= welcome_message(user) %>
Notez que le décorateur/présentateur propose une approche orientée objet vraiment propre, mais à mon humble avis, utiliser un assistant est beaucoup plus simple et suffisant.
Non, vous ne voulez pas tout conditionnels du tout dans la classe d'utilisateur ni le contrôleur.Le point de cet exemple sur le blog post est de faire référence au polymorphisme, juste une bonne vieille conception OO.
# in application_controller for example
def current_user
if signed_in?
User.find(session[:user_id])
else
Guest.new
end
end
#app/models/user.rb
class User
def welcome_message
"hello #{name}"
end
end
#app/models/guest.rb
class Guest
def welcome_message
"welcome newcomer"
end
end
... vous obtenez l'idée.
Seulement, au lieu de jeter votre modèle avec des méthodes de présentation uniquement, créez un décorateur qui agit comme un présentateur:
require 'delegate'
class UserPresenter < SimpleDelegator
def welcome_message
"hello #{name}"
end
end
Et maintenant current_user
ressemble à:
# application_controller
def current_user
if signed_in?
UserPresenter.new(User.find(session[:user_id]))
else
Guest.new
end
end
Décorez le modèle utilisateur et ajoutez directement le bienvenue_message.Oui, cela peut impliquer une sorte de déclaration conditionnelle à un moment donné.
Je pense que vous devriez regarder l'épisode Railscasts sur les présentateurs pour la réponse.
La logique dans la vue est difficile à maintenir, nous devrions mettre la logique commerciale dans le modèle et toutes les logiques de la logique chez les aides.
Si vous souhaitez que votre code soit en mode orienté objet, utilisez des décorateurs (mode orienté objet d'assistants)
meilleur exemple: https://github.com/jcasimir/draper
Mettez le code définissant current_user.welcome_message
dans _app/helpers/application_helper.rb_, il sera alors accessible par n'importe quelle vue rendue avec le application mise en page.
Une autre option consiste à définir un coutume module d'assistance, celui qui n'est pas nécessairement associé à une vue ou un contrôleur donné (voir la vidéo que j'ai liée ci-dessous), et include
dans les modules de la vue/des contrôleurs dans lesquels vous souhaitez avoir cette fonctionnalité.
Ce n’est pas quelque chose de noir ou blanc.Mais, d'après ce que vous avez décrit, il semble que ce soit du code qui est intrusif à coller dans votre application_controller.rb et ce n'est pas du code avec des fonctionnalités qui justifient son propre contrôleur, l'option la plus efficace et la plus efficiente peut être de créer un module d'assistance personnalisé. et incluez-le dans les assistants pour lesquels vous souhaitez avoir cette fonctionnalité.Cela dit, il s'agit en fin de compte d'une question de jugement que le concepteur de l'application (c'est-à-dire toi) doit être décidé.
Ici est un bon article décrivant les modules d'aide de Mai 2011
Ici c'est un plan RailsCast coutume modules d'assistance (c.-à-d.personnalisé comme dans les modules pas nécessairement associés à un contrôleur ou une vue donnée).Court, doux et précis.
Vous pouvez définir la méthode de l'assistance pour ce genre de choses.Je ne pense pas que ce soit une bonne idée de faire une phrase de bienvenue dans un modèle, mais dans le contrôleur aussi.Mais vous devriez essayer de vous faire des vues propres à partir du code et si vous pouvez utiliser des aides pour cela, vous devriez.
Une bonne pratique serait d'avoir de vrais View
instances.La parodie Rails de MVP (il y a une différence, recherchez-la) semble malheureusement prétendre que les vues sont des modèles.C'est faux.
Les vues sont censées contenir la logique de présentation dans des modèles inspirés de MVC et de MVC.Ils sont également censés manipuler plusieurs modèles et décider quels modèles utiliser pour représenter l'état et les informations de la couche modèle (oui, le modèle est une couche et non une instance ORM).
Alors pour répondre à la question : la logique de présentation n'a pas sa place dans les contrôleurs.