Modèles non-ActiveRecord dans Rails 4

ActiveRecord est livré avec un ensemble puissant de validateurs et d'autres fonctionnalités pour les attributs d'un modèle de données conservé. D'autre part, les formulaires constituent l'un des blocs de construction les plus anciens et les plus importants des applications Web actuelles - une interface essentielle pour la saisie de l'utilisateur. Parmi les deux aides de formulaire fournies par Rails, "formulaire_pour" suppose également que vous travaillez avec un type d'objet persistant. Ainsi, il peut tirer pleinement parti de toutes les fonctionnalités d’enregistrement actif, c’est-à-dire des validations..

Ceci est idéal pour les objets persistants avec des représentations basées sur une base de données. Mais que se passe-t-il lorsque vous avez besoin d’un formulaire complexe qui ne reflète pas un enregistrement persistant quelconque??

Dans ce tutoriel, je parlerai des solutions possibles à ce problème et de la mise en œuvre de celle-ci dans Rails 4 (modèles actifs)..

Dans ce tutoriel, nous construirons une application avec un formulaire dans lequel un utilisateur peut ajouter des commentaires qui sont ensuite enregistrés dans une base de données. Cette application comportera également des validations et des vues, exactement comme vous les créez pour un modèle basé sur une base de données, mais nous passerons ensuite en revue certaines des modifications apportées au modèle pour le rendre sans tableau. Et toutes les fonctionnalités doivent fonctionner comme elles sont, sans autre modification. Aucune action de mise à jour, de suppression ou de recherche de commentaires.

Premières choses d'abord

Pour ce tutoriel, je suppose que vous avez une compréhension de base du framework Rails et que vous pouvez facilement créer ou générer des contrôleurs, des modèles et des vues de base. Je suppose que vous en savez aussi un peu sur le fonctionnement des routes et des validations. Au moment de l'écriture de ce tutoriel, j'utilisais Rails 4.2.5 et SQLite 3.8.10.2.

introduction

Il peut y avoir de nombreuses situations dans lesquelles vous souhaitez utiliser une classe comme un modèle ActiveRecord typique, mais vous ne souhaitez pas conserver les données dans la base de données. Par exemple, vous pouvez avoir un formulaire de contact ou quelque chose de plus complexe, comme un formulaire de plainte ou de feedback. 

Dans ces situations, pour résoudre ce problème, une approche consisterait à utiliser le form_tag méthode d'assistance, qui vous fournit des champs de formulaire personnalisés qui font ce dont vous avez besoin sans avoir à les lier à aucun modèle.

Cela fonctionne bien, mais form_tag peut rapidement devenir fastidieux à écrire et à entretenir si vous manipulez plusieurs champs à cause de la nécessité de gérer vous-même la dénomination de ses nombreux attributs et de leurs validations. Bientôt, votre contrôleur devra faire face à beaucoup de logique et à des tonnes de paramètres de formulaire, ce qui n’est probablement pas une solution idéale.

Une approche plus propre et plus flexible consisterait à utiliser le même formulaire_pour avec un modèle et toutes les validations et autres avantages associés, mais sans avoir besoin de représentations de ses attributs basées sur une base de données.

Rails propose exactement ce type de solution: le Modèle actif-qui est juste comme un modèle normal mais sans les tables. Il fournit exactement le même moyen simple de validation et presque tous les autres produits livrés avec ActiveRecord. Cela vous aide à maintenir la cohérence de la structure de l'application, car vous utilisez quand même des modèles pour représenter des objets dans votre application, les itinéraires sont disponibles gratuitement et la création de formulaires est aussi simple qu'avant. formulaire_pour.

Créons d'abord une nouvelle application

Dans cette étape, nous allons générer une application fictive avec laquelle vous pourrez jouer pendant ce tutoriel..

Étape 1: construction

Démarrez votre terminal et tapez ces commandes pour créer une nouvelle application:

# Créer une base Rails App rails un nouveau cd sans tableau # Créer un contrôleur avec uniquement de nouvelles fonctions Créer, créer et réussir Actions rails génèrent les retours du contrôleur Nouveau Créer un succès --skip-routes # Créer un modèle Les rails génèrent le retour du modèle nom: string email: string address : message de chaîne: suggestion de texte: texte 

Voici comment votre Structure du répertoire jettera un coup d'oeil.

Étape 2: édition

Ici, je vais fournir les extraits de code pour tous les fichiers que vous devez remplir. Le code est assez explicite. Vous pouvez soit télécharger cette application à partir du référentiel GitHub lié à ce message, soit suivre mes étapes pour en créer une par vous-même..

→ / config /routes.rb

ressources: feedbacks,: only => [: new,: create] get 'feedbacks / success' => 'feedbacks # success', en tant que:: success

→ /app/views/feedbacks/success.html.erb

<%= notice %>


<%= link_to 'Submit New Feedback', new_feedback_path %>

→ / app / vues / commentaires /new.html.erb 

Nouveau feedback

<%= form_for(@feedback) do |f| %> <% if @feedback.errors.any? %>

<%= pluralize(@feedback.errors.count, "error") %> a interdit que ce retour soit sauvegardé:

    <% @feedback.errors.full_messages.each do |message| %>
  • <%= message %>
  • <% end %>
<% end %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :message %>
<%= f.text_area :message %>
<%= f.label :suggestion %>
<%= f.text_area :suggestion %>
<%= f.submit %>
<% end %> <%= link_to 'Back', feedbacks_path %>

→ /app/controllers/feedbacks_controller.rb

classe FeedbacksController < ApplicationController def new @feedback = Feedback.new end def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.save format.html  redirect_to success_path, notice: 'Feedback was successfully submitted.'  else format.html  render :new  end end end def success end private def feedback_params params.require(:feedback).permit(:name, :email, :address, :message, :suggestion) end end

→ / app /modèles / feedbacks.rb

Commentaires sur la classe < ActiveRecord::Base # fields validation for the database. validates :name, presence: true validates :email, presence: true, length: in:5… 255 validates :address, presence: true validates :message, presence: true validates :suggestion, presence: true end

Étape 3: déploiement

Pour le déployer sur votre serveur local, vous devez d’abord exécuter les commandes suivantes pour créer la base de données sur votre système..

cd tableless / rake db: migrer 

Si vous avez suivi le didacticiel jusqu'à présent, la commande ci-dessus devrait créer une base de données sqlite3 par défaut. Pour le changer, vous pouvez aller à database.yml-par souci de ce tutoriel, je vais aller avec sqlite3.

Maintenant courir rails s dans votre terminal et vous devriez voir quelque chose de similaire à cela.

Et avec cela, vous devriez exécuter avec succès une application factice.

Étape 4: test

Il est maintenant temps de tester ce que nous venons de créer. Suivez cette route dans votre navigateur pour vérifier si tout fonctionne bien: http: // localhost: 3000 / feedbacks / new

Vous devriez voir un formulaire comme ci-dessus. Maintenant, appuyez sur le bouton d'envoi sans remplir aucun champ pour vérifier si les validations fonctionnent correctement..

Génial. Vous devriez voir six erreurs de validation, comme ci-dessus. Maintenant, nous pouvons essayer de renseigner les valeurs appropriées et de soumettre le formulaire..

Vous devriez voir quelque chose de similaire sur votre écran. Vérifions la base de données pour l'enregistrement que nous venons d'entrer. 

Ouvrez votre Terminal, allez dans le répertoire de votre projet et tapez les commandes ci-dessous.

  • rails db démarrer le client de base de données dans votre console.
  • SQLite> .tables pour lister toutes les tables de votre base de données (DB est sélectionné par défaut).
  • SQLite> .headers sur pour afficher le Noms de colonne dans vos résultats.
  • SQLite> select * from feedbacks; pour voir tous les commentaires dans la base de données.

Et nous pouvons voir ici que les commentaires ont été enregistrés avec succès dans la base de données. Si vous regardez dans les journaux, vous pouvez également trouver le INSÉRER question.

Et avec cela, nos tests sont terminés. Maintenant que tout semble bien fonctionner, passons à la solution.

La solution

Étape 1: mise en œuvre 

Implémenter Modèle actif, la première chose que vous devez faire est de supprimer l'héritage du modèle de feedback < ActiveRecord::Base comme nous ne voulons plus que ce modèle ait un back-end de base de données. 

Dès que nous faisons cela, notre formulaire ne fonctionnera plus, car les validateurs sont fournis par ActiveRecord. Mais en ajoutant include ActiveModel :: Model sur la ligne suivante devrait tout restaurer.

Votre modèle devrait ressembler à ceci maintenant.

commentaires de classe incluent ActiveModel :: Model 

La deuxième chose est d'ajouter attr_accessor pour générer les getters et setters de tous les attributs, comme ceci.

attr_accessor: nom,: email,: adresse,: message,: suggestion

Maintenant, le résultat final du modèle devrait ressembler à ceci.

class Feedback inclut ActiveModel :: Model attr_accessor: nom,: email,: adresse,: message,: suggestion # validation des champs pour la base de données. valide: nom, présence: vrai valide: email, présence: vrai, longueur: in: 5… 255 valide: adresse, présence: vrai valide: message, présence: vrai valide: suggestion, présence: vrai fin

Réparer le modèle ne suffit pas pour que notre application se comporte comme nous le souhaitons. Le contrôleur s’attend toujours à enregistrer l’objet de données reçu dans la base de données dans créer méthode. @ feedback.save ne fonctionnera pas car nous n'avons pas de base de données pour sauvegarder les nouveaux commentaires.

Nous pouvons résoudre ce problème en modifiant @ feedback.save dans @ feedback.valid? étant donné que nous n'effectuons que les validations dans nos modèles maintenant, et en fonction de cet événement de réussite, vous pouvez effectuer n'importe quelle tâche de votre choix dans ce bloc de code, c'est-à-dire envoyer des notifications, envoyer des courriels ou consigner des événements, etc..

classe FeedbacksController < ApplicationController def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.valid? # Something interesting can be done here # - send notifications # - send email # - log events format.html  redirect_to success_path, notice: 'Feedback was successfully submitted.'  else format.html  render :new  end end end

Étape 2: test

Reprenons les tests que nous avons effectués précédemment.

Hit la route http: // localhost: 3000 / feedbacks / new et soumettrele formulaire sans remplir aucun champ. Toutes les validations devraient fonctionner comme auparavant.

Génial. Maintenant, nous pouvons essayer en soumettant le formulaire avec des valeurs valides.

Et voilà le même message de réussite.

Maintenant, la dernière chose que nous devons vérifier est la base de données. 

Pour cela, ouvrez votre Terminal, allez dans le répertoire de votre projet et tapez les commandes ci-dessous.

  • rails db démarrer le client de base de données dans votre console.
  • SQLite> .tables pour lister toutes les tables de votre base de données (DB est sélectionné par défaut).
  • SQLite> .headers sur pour afficher le Noms de colonne dans vos résultats.
  • SQLite> select * from feedbacks pour voir tous les commentaires dans la base de données.

Et cette fois, étant donné que notre modèle n'est associé à aucune table de base de données, vous ne trouverez pas les nouvelles valeurs soumises dans la table..

Si vous consultez les journaux de votre console, nous ne voyons pas non plus le INSÉRER interroger plus.

Conclusion

Donc, avec cela, nous en avons fini avec le ActiveModel, et nous avons vu à quel point il est facile de créer un modèle sans table. ActiveModel fait l'objet de nombreuses améliorations, vous pouvez donc vous attendre à quelques modifications dans les prochaines versions de Rails.. 

Nous venons d'utiliser les validations et attributions d'attributs de ce tutoriel afin de garder les choses simples et claires. Mais jetez un oeil dans le répertoire qui contient le code pour ActiveModel sur GitHub.

Nous pouvons voir dans la liste qu'ActiveModel inclut également des classes pour les méthodes d'attribut, la sérialisation, les rappels et le suivi modifié, entre autres. De cette façon, vous pouvez garder un œil sur les fonctionnalités à venir et également vous familiariser avec les autres..