Si vous n’êtes pas dans Rails 6, il vous faudra ajouter la gem Active Storage dans votre Gemfile et l’installer avec la commande bundle install
.
# Gemfile
gem 'activestorage'
On va l’installer avec la commande rails active_storage:install
et créer les tables liant les photos aux modèles avec rails db:migrate
.
$ rails active_storage:install
$ rails db:migrate
Ensuite nous allons attacher des images à notre modèle Flat
. Attention, contrairement à d’autres gems, il n’y a pas besoin de créer un nouveau champ.
class Flat < ApplicationRecord
has_many_attached :images
# Si vous ne souhaitez attacher qu'une seule image :
# has_one_attached :image
end
Dans le flats_controller
, il faut autoriser l’upload d’images.
# app/controllers/flats_controller.html.erb
def flat_params
params.require(:flat).permit(:title, :content, images: [])
end
Et dans la vue du formulaire, on ajoute un champ pour les images.
<!-- app/views/flats/new.html.erb -->
<%= simple_form_for flat do |f| %>
[...]
<%= f.file_field :images, multiple: true, class: "form-control" %>
<!-- Si vous avez qu'une seule image -->
<%#= f.file_field :image, class: "form-control" %>
[...]
<% end %>
Le formulaire est désormais utilisable sur localhost
. On va donc afficher les images sur la show
d’un flat.
Comme je récupère un tableau d’images, je vais pouvoir itérer dessus et les inclure dans un caroussel Bootstrap.
<!-- app/views/flats/show.html.erb -->
<div class="flat-content">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<!-- Vous pouvez remplacer @flat par votre modèle -->
<% @flat.images.each_with_index do |image, index| %>
<div class="carousel-item <%= "active" if index == 0%>">
<%= image_tag image, height: 500, width: 700 %>
</div>
<% end %>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
Suivre le tuto ici
Le champ d’upload a nativement très peu de style.
Tout d’abord, nous allons modifier notre formulaire. Attention il faut que le label ait le même nom que votre l’id de votre input Simple Form. Dans notre cas c’est flat_images
. Pour une image cela aurait été flat_image
. Je rajoute un div qui va accueillir le nom des fichiers. Et j’ajoute la classe d-none
à l’ancien input de téléchargement des images.
<!-- app/views/flats/_form.html.erb -->
[..]
<%= simple_form_for flat do |f| %>
[..]
<label for="flat_images" class="btn-upload">
Upload tes photos <i class="fas fa-cloud-upload-alt"></i>
</label>
<div id="flat-images-filename"></div>
<%= f.file_field :images, as: :file, multiple: true, class: "form-control d-none" %>
[..]
<% end %>
[..]
/* app/assets/components/_button.scss */
.btn-upload {
/* Enrichissez ici le style de votre button */
cursor: pointer
}
// app/javascript/packs/application.js
$("#flat_images").change(function() {
Array.from(this.files).forEach((element) => {
document.getElementById("flat-images-filename").innerHTML += `${element.name}<br>`
});
});
Publié le 15/09/2019