Le Blog du Geek Joyeux

Plus moins vite tu codes, moins plus vite ça plante

Utiliser HasScope avec Padrino

| Commentaires

Pour ceux qui ne connaissent pas, HasScope est une gem Ruby qui permet d’utiliser les scopes de vos modèles Active Record comme des filtres dans vos URLs.

Pour faire simple, imaginons que vous ayez le modèle suivant :

1
2
3
4
class Person < ActiveRecord::Base
  scope :alive,  where(alive: true)
  scope :gender, lambda { |gender| where(gender: gender) }
end

Pour rendre ces scopes accessibles dans les URLs, il vous suffit, une fois la gem has_scope installée dans votre projet d’ajouter les lignes suivantes dans votre contrôleur:

1
2
3
4
5
6
7
8
class PeopleController < ApplicationController
  has_scope :alive, :type => :boolean
  has_scope :gender

  def index
    @people = apply_scopes(Person).all
  end
end

Il vous est maintenant possible d’appeler les URLs suivantes:

1
2
3
/people?alive=true              # Liste des personnes vivantes
/people?gender=male             # Liste des hommes
/people?gender=male&alive=true  # Liste des hommes vivants

Padrino

Malheureusement, HasScope est écrit pour Rails, elle n’est donc pas compatible avec Padrino.

Il existe cependant une gem sinatra-has_scope qui permet d’obtenir le même comportement dans Sinatra.

Puisque Padrino est basé sur Sinatra, il est possible d’intégrer cette petite gem dans votre projet. Voici comment.

Commencez par ajouter la gem à votre Gemfile:

1
gem 'sinatra-has_scope', :require => 'sinatra/has_scope'

Puis lancez le classique bundle install.

Une fois cela fait, ajoutez la ligne suivante dans chaque application de votre projet où vous comptez utiliser le mécanisme.

1
2
3
class MyApp < Padrino::Application
  include Sinatra::HasScope
end

Vous pouvez maintenant faire appel à vos scopes dans les différents contrôleurs concernés:

1
2
3
4
5
6
7
8
9
10
MyApp.register :people do
  before do
    has_scope :people, :alive, :type => :boolean
    has_scope :people, :gender
  end

  get :index do
    @people = apply_scopes(:people, Person, params).all
  end
end

Notez ici une légère différence, les scopes sont préfixés du nom de la ressource. Ceci est dû au fait que les contrôleurs ne sont pas des classes indépendantes mais des blocs de code, cela signifie que tous les scopes sont stockés au niveau de la classe MyApp. On les préfixe donc pour éviter toute collision.

L’application des scopes est également légèrement différente puisqu’on lui passe explicitement le préfixe et params mais le résultat est le même.

Commentaires