Ruby On Rails

Université de REIMS - 2019



Christian Pennaforte
Framework




C'est quoi...
un framework ?


Ensemble d'outils...


... pour ne pas réinventer la roue.





Ruby On Rails

est un framework !

Ruby

こんにちは Ruby !



Inventé en 1995 par Yukihiro « matz » Matsumoto

Langage de script simple mais puissant et efficace


Parenthèses optionnelles

Pas de ;


Tout est objet

Gestion d’exceptions, ramasse-miettes

Diverses implémentations (Linux, Mac, Win, java...)

   

Interpréteur interactif en ligne de commande : irb


> "bonjour " * 3
=> "bonjour bonjour bonjour "

> aujourdhui = Date.today
=> 

> demain = aujourdhui + 1.day
=> 

> dans_une_semaine = aujourdhui + 1.week
=> 
						

> ["Dog", "Fox", "Mouse"].each do |animal|
  puts "I like #{animal.pluralize}"
end

I like Dogs
I like Foxes
I like Mice
 => ["Dog", "Fox", "Mouse"]
 						

Ruby (On Rails) connait le pluriel des mots... anglais


> chaine = "C'est chouette l'IUT"
=> "C'est chouette l'IUT"

> tableau = chaine.split(" ")
=> ["C'est", "chouette", "l'IUT"]

> tableau.reverse.map{|ch| ch.capitalize}.join("+")
=> "L'IUT+Chouette+C'est"
						

Il y a plein de méthodes pratiques sur la classe Array


N'hésitez pas
à pianoter dans la console !


class Personne < ActiveRecord::Base

  def nom_complet
    prenom+" "+nom
  end

  def age
    ((Date.today - date_naissance)/365.25).floor
  end

end
  
            
p = Personne.new
puts p.age
            
          

Quelques règles de notation


une_variable_toute_simple

:un_symbole

UneClasse

@une_variable_d_instance

@@une_variable_de_classe

UNE_CONSTANTE

$une_abominable_variable_globale # beurk !

Les variables sont typées, mais on ne définit pas les types des variables explicitement.

C'est ce qu'on appelle le Duck Typing.


# Fichier : ma_classe.rb
class MaClasse

	def ma_methode_d_instance
		# La dernière ligne d'une méthode est renvoyée
		# (c'est un return implicite)
		"Bye bye !"
	end

	def self.ma_methode_de_classe
		MaClasse.new nom:"Dupont"
	end

end
							
Qui s'utilise ainsi :

> mon_objet = MaClasse.ma_methode_de_classe
> mon_objet.ma_methode_d_instance

=> "Bye bye !"
							

Où trouver de la doc ?



Sur internet bien sûr (Google est votre ami)



Pour démarrer :

http://www.ruby-lang.org/fr/documentation/quickstart

La référence du langage sur devdocs.io:

http://devdocs.io/ruby/

Pour apprendre de manière interactive et ludique :

Try Ruby !, RubyMonk et Ruby Warrior !
Les Gems

Paquet contenant des classes Ruby et des outils


Provenant d'un dépôt d'internet

Exemples :


XML, SOAP, Google docs, spreadsheet, lastfm, sqlite, mysql, pg, devise, pdf, twitter-bootstrap, ckeditor, facebook, et... Rails !

Les commandes shell utiles


# Liste des gems installées :
$ gem list

# Installer une gem :
$ gem install

# Chercher une gem :
$ gem search 

# Mettre à jour les gems d'un projet avec Bundler :
$ bundle
						
+
= !
Ruby On Rails

Principes


Convention Over Configuration

DRY : Don’t Repeat Yourself !

MVC : Modèle Vue Contrôleur

Conventions

PersonneLa classe s'écrit en CamelCase
personnesLa table associée à une classe est au pluriel
date_de_naissanceUn attribut s'écrit en snake_case
adresse_idLa clé étrangère = nom de l'assoc. + _id
personne.rbLe fichier qui contient la classe porte son nom en snake_case


app/models/personne.rb
app/controllers/personnes_controller.rb
app/views/personnes/index.html.erb
Chaque fichier a un nom correspondant à ce qu’il contient

DRY

Rails offre de nombreux mécanismes
pour ne pas dupliquer de code

Partialssous-vues pouvant être appelées par d'autres vues
Helpersfonctions appelées par les vues
Héritageclassique du développement objet
Gemscompléments pour ajouter des fonctionnalités

Modèle Vue Contrôleur


Permet d'organiser et de découper l'application pour :

  • faciliter la maintenance
  • écrire moins de code
  • être plus logique


Le modèle contient la logique métier et l'accès aux données

Le contrôleur reçoit des requêtes HTTP et génére la Vue en se servant du modèle

M V C




Le modèle

Le modèle


Ruby (+SQL)

Persistance

La classe sait charger et sauvegarder ses objets dans la base de données = SQL automatique (pas de SQL à écrire)

Associations

Description des liaisons des classes entre elles = jointures automatiques

Le modèle


Ruby (+SQL)

Migrations

On passe d'un schéma de base à l'autre en une commande (et vice-versa)

Validations

Les contraintes d'unicité, de format, etc. sont portées par la classe, pas par la BD et surtout pas par autre chose

Le modèle

Exemple de migration

class CreateVoitures < ActiveRecord::Migration

   def self.up
     create_table :voitures do |t|
       t.string :immatriculation
       t.string :marque
       t.string :modele
       t.string :couleur
       t.timestamps
     end
   end

   def self.down
     drop_table :voitures
   end

end
						
						

Le modèle

Exemple de migration

class AddPersonneIdToVoiture < ActiveRecord::Migration
  def self.up
    add_column :voitures, :personne_id, :integer
  end
  def self.down
    remove_column :voitures, :personne_id
  end
end
						
						

Le modèle

Exemple d'utilisation depuis la console Rails

# Exemple d’utilisation des classes du modèle
paul = Personne.new
paul.nom = «Dupont»
paul.prenom = «Paul»
paul.save

v = Voiture.create(immatriculation: «123 ABC 51», marque: «Peugeot»)
v.personne = paul

#   ou

paul.voitures << v
puts paul.voitures.count
-> 1

puts Voiture.first.personne.nom
-> «Dupont»
						
						

le modèle





Le contrôleur

Le contrôleur

Ruby
Route URL + Verbe → Contrôleur + action
Action méthode appelée par un verbe HTTP
Layout choix d’un modèle de vue pour rendre une action
Filtres utilisé pour l’authentification et pour protéger les accès aux actions

Sessions session['valeur']=objet
Paramètres params['nom'] (par exemple)

La taille du code d’un contrôleur doit rester petite !




La vue

la vue


HTML + Ruby + CoffeeScript + CSS

Modèles des vues

Permettent de donner de la cohérence à l'affichage
views/layouts/application.html.erb

Partials

Sous-vues, dans des fichiers indépendants (commençant par _)


Helpers

Fonctions facilitant l'écriture des vues et évitant de dupliquer du code (génération de formulaire, liens, champs...)




Mais comment tout ça s'articule ?




Vous le saurez en regardant cette petite animation.

Les routes

Verbe + chemin d'URL + paramètres nommés

Contrôleur + Action


# Fichier config/routes.rb
get '/personnes/par_nom/:nom' => 'personnes#show_par_nom', as:"montrer_par_nom"

	Exemple d'URL : http://mon_serveur:3000/personnes/show_par_nom/DUPONT

# Fichier app/controllers/personnes_controller.rb
class PersonnesController < ApplicationController
  # GET /personnes/par_nom/DUPONT
  def show_par_nom
    # Dans params[:nom], on a le nom passé sur l'URL
  end
end

Génération d'une URL depuis une route

Nom de la route + _path(paramètres)
montrer_par_nom_path("un nom")

# Exemple pour générer un lien :
<%= link_to @personne.nom, montrer_par_nom_path(@personne.nom) %>



Déduction d'après les conventions
Classe Personne → Instance @personne
<%= link_to @personne.nom, @personne %>
# est équivalent à
<%= link_to @personne.nom, personne_path(@personne.id) %>
→ /personnes/32 # On suppose que @personne à l'id 32

Les conventions du MVC

Contrôleur → Vue → FormBuilder → Page HTML

Exemple : app/views/questions/_form.html.erb


<%= form_for @question do |f| %>
	Libellé : <%= f.text_field :libelle %>
<% end %>
						

<form action="/questions/3" class="edit_question" id="edit_question_1" method="post">
  <div class="field">
    <label for="question_libelle">Libellé</label><br />
    <input id="question_libelle" name="question[libelle]" size="30" type="text" value="04- Durée depuis..." />
  </div>
  <div class="actions">
    <input name="commit" type="submit" value="Update Question" />
  </div>
</form>
						

Page HTML → Submit → Contrôleur

Exemple : app/controllers/questions_controller.rb


params == {:question => {:libelle => "04 - Comment ça va aujourd'hui ?"},
           :id => 3}
						
soit

params[:question] == {:libelle => "04 - Comment ça va aujourd'hui ?"}
						
on peut donc écrire

mon_objet_a_mettre_a_jour = Question.find(params[:id])
mon_objet_a_mettre_a_jour.update_attributes(params[:question])
						

Les associations nichées

Dans le modèle :

class Personne < ActiveRecord::Base
  has_many :voitures
  accepts_nested_attributes_for :voitures, allow_destroy: true
end
Dans le fichier Gemfile :

gem 'nested_form'
N'oubliez pas le bundle install
Dans la vue :

<%= nested_form_for @personne %>
	...
	<%= f.fields_for :voitures  %>
	...
<% end %>
et pensez à créer le partial : app/views/personnes/_voiture_fields.html.erb
il s'affichera pour chaque objet niché (voiture ici)

CoffeeScript


Certes, l'impatience d'en savoir plus vous ronge, mais le monde n'est pas fait que d'instantanéité.
Cette section sera développée un peu plus tard.

On parlera de JavaScript et Ajax, mais on utilisera un langage plus concis que JavaScript (mais tout à fait compatible avec).
Anatomie d’un
projet RoR

Anatomie d’un projet RoR

app

  • Les vues (html + ruby)
  • les assets (html, css, coffeescript et javascript)
  • les modèles (un par classe)
  • les contrôleurs (souvent un par classe)
  • les helpers (petites fonctions ruby qui évitent d'en écrire trop dans la vue)

Attention aux conventions de nommage.


Quand vous modifiez un de ces fichiers, le serveur est automatiquement à jour en mode développement, et la console Rails nécessite un petit rechargement avec la commande :

reload!

config

  • initializers : classes et outils servant toutes les autres classes
  • database.yml : description des connexion de bases de données (dév, test et prod)
  • locales : fichiers de traduction pour les applications multilingues
  • routes.rb : description des resources et des urls en lien avec leurs contrôleurs / actions


Tout ce qui est modifié dans ce répertoire nécessite un redémarrage de la console ou du serveur (Ctrl-C, puis rails c ou rails s).

Gemfile

  • Gemfile : la liste des Gems de votre projet.


Si vous faites une modification dans ce fichier, quittez le serveur / la console Rails puis mettez à jour vos gems avec la commande shell "bundle install"

db

  • Le fichier contenant la base sqlite3 (si c'est ce qui est utilisé)
  • Les classes de migration, pour mettre à jour la base de données


  • Laissez rails gérer ces fichiers pour vous ; ne les effacez jamais, il pourront vous être utiles.

Commandes du shell sous Linux


# Générer un nouveau projet
rails new nom_projet
cd nom_projet

# Vérifie et installe les Gems requise par le projet (dans le fichier Gemfile, décommenter therubyracer, on en a besoin)
bundle install

# Génère le modèle, la vue, le contrôleur et la migrations prêts à l'emploi
rails generate scaffold Classe <attribut[:type]> <attribut[:type]>

# Lance un serveur Rails
rails server [-p port]

# Lance IRB dans l’environnement Rails
rails console

# Joue / annule les dernière migrations
rake db:migrate / rollback

# Exécute un script dans l'environnement Rails de votre projet
rails runner lib/tasks/<nom du script>

						
Petit exemple pour démarrer

# On génère un nouveau projet «tp_1»
# (la base de données par défaut est sqlite3)
rails new tp_1

# On va dans le répertoire du projet
cd tp_1

# On active la gem "therubyracer" dans le fichier Gemfile
# et on vérifie que l’environnement de la machine est adapté au projet
bundle install

# On crée une nouvelle classe, sa vue, son contrôleur...
rails generate scaffold Personne nom prenom date_de_naissance:date

# On crée la table correspondant dans la base de donnéees
rake db:migrate

# On lance le serveur
rails server
						

Les outils

  • CodeAnywhere.com : environnement hébergé = 0 config :-)
  • Cliquez ici pour vous créer un compte gratuit.
  • Le Shell
  • 								
    rails new <projet>
    rake db:migrate
    rails generate ...
    								
    							
  • La console Rails (pour écrire du code Ruby)
  • Le navigateur moderne (Firefox + Firebug / Chrome)
  • Les petites Gem utiles au développeur
    • awesome_print, better_errors
    • rails_best_practices, meta_request

Où trouver de la doc ?


Sur internet bien sûr (Google est toujours votre ami)


Suivez le guide

http://guides.rubyonrails.org

Fouillez dans les API

http://api.rubyonrails.org
http://devdocs.io/rails/

Regardez des screencasts pour apprendre plein de choses

http://www.railscasts.com

Pour apprendre de manière ludique

Rails for zombies !
Travaux Pratiques

Travaux
pratiques

Le sujet se trouve ici.