See the Devise repository for more information.
-
Add
gem "devise"
to the Gemfile and run:bundle install rails generate devise:install
Then follow the instructions displayed in the terminal.
-
Generate a devise model with
rails generate devise User
. -
Protect every route by default:
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :authenticate_user! end
-
Skip the login for some pages:
# app/controllers/pages_controller.rb class PagesController < ApplicationController skip_before_action :authenticate_user!, only: :home def home end end
-
When adding new attributes to a devise model, specify them in the
ApplicationController
:# app/controllers/application_controller.rb class ApplicationController < ActionController::Base # [...] before_action :configure_permitted_parameters, if: :devise_controller? def configure_permitted_parameters # For additional fields in app/views/devise/registrations/new.html.erb devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name]) # For additional in app/views/devise/registrations/edit.html.erb devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name]) end end
-
Optionally customize devise routes.
See the JavaScript in Rails guide for more information.
Generate Stimulus controllers with:
rails generate stimulus CONTROLLER_NAME
importmap pin $NAME_OF_THE_LIBRARY
For example, to use flatpickr.js:
-
Install the library and import the stylesheet in your main layout:
importmap pin flatpickr
<!-- app/views/layouts/application.html.erb --> <!-- ... --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
-
Create a specific
datepicker
controller:rails generate stimulus datepicker
// app/javascript/controllers/datepicker_controller.js import { Controller } from '@hotwired/stimulus' import flatpickr from 'flatpickr'; export default class extends Controller { connect() { flatpickr(this.element) } }
-
Add the controller to the view:
<%= f.input :opening_date, as: :string, input_html: { data: { controller: "datepicker" } } %>
-
Set up the controller to return a JSON response using
respond_to
:# app/controllers/monuments_controller.rb # [...] def create @monument = Monument.new(monument_params) respond_to do |format| if @monument.save format.html { redirect_to monument_path(@monument) } format.json # looks for a create.json view else format.html { render "monuments/new", status: :unprocessable_entity } format.json # looks for a create.json view end end end
-
Make sure that the
jbuilder
gem is installed and create acreate.json.jbuilder
view:# app/views/monuments/create.json.jbuilder if @monument.persisted? json.form render(partial: "monuments/form", formats: :html, locals: { monument: Monument.new }) json.inserted_item render(partial: "monuments/monument", formats: :html, locals: { monument: @monument }) else json.form render(partial: "monuments/form", formats: :html, locals: { monument: @monument }) end
-
Generate a new Stimulus controller to handle the request:
rails generate stimulus insert_in_list
// app/javascript/controllers/insert_in_list_controller.js import { Controller } from '@hotwired/stimulus' export default class extends Controller { static targets = ['items', 'form'] send(event) { event.preventDefault(); fetch(this.formTarget.action, { method: 'POST', headers: { Accept: 'application/json' }, body: new FormData(this.formTarget) }) .then(response => response.json()) .then((data) => { if (data.inserted_item) { this.itemsTarget.insertAdjacentHTML('beforeend', data.inserted_item) } this.formTarget.outerHTML = data.form }) } }
-
Connect the controller to the DOM:
<!-- app/views/monument/index.html.erb --> <div class="container"> <div class="row"> <div class="col" data-controller="insert-in-list"> <div id="monuments" data-insert-in-list-target="items"> <!-- ... --> </div> </div> </div> </div>
<!-- app/views/monument/_form.html.erb --> <%= simple_form_for monument, data: { insert_in_list_target: "form", action: "submit->insert-in-list#send" } do |f| %> <!-- ... --> <% end %>
-
Install and configure the geocoder gem:
# Gemfile # ... gem "geocoder"
bundle install rails generate geocoder:config
# config/initializers/geocoder.rb Geocoder.configure( # [...] units: :km, # Defaults to miles (:mi) )
-
Add the coordinates columns and update the model:
rails g migration AddCoordinatesToFlats latitude:float longitude:float rails db:migrate
# app/models/flat.rb class Flat < ApplicationRecord geocoded_by :address after_validation :geocode, if: :will_save_change_to_address? end
-
Create a geocoded instance and search for nearby instances:
# rails console Flat.create(address: "16 Villa Gaudelet, Paris", name: "Le Wagon HQ") # => #<Flat:0x007fad2e720898 # id: 1, # name: "Le Wagon HQ", # address: "16 Villa Gaudelet, Paris", # latitude: 48.8649574, # longitude: 2.3800617> Flat.near("Tour Eiffel", 10) # flats within 10 km of Tour Eiffel Flat.near([40.71, 100.23], 20) # flats within 20 km of a point