Skip to content
danillos edited this page Apr 19, 2011 · 1 revision

Introdução

Scopes permite que você crie métodos para as consultas mais usadas em sua aplicação. Com eles o códido da aplicação fica mais limpo, mais fácil de entender e reaproveitável assim então ganhando maior mantenabilidade.

Em um blog por exemplo, quando é preciso buscar um post de uma determinada categoria o código da consulta com o DrumonModel normalmente seria parecido com este:

<?php
  class PostController extends AppController {
    
    public function show_category() {
      $post = new Post();
      $posts = $post->where('category = ?', array($this->params['category']));
      $this->add('posts',$posts);
    }
    
  }
?>

Se em outros locais da aplicação é preciso fazer essa mesma consulta o código da consulta ficaría duplicado, aumentado então o trabalho durante a manutenção dessa aplicação.

<?php
  class PostController extends AppController {
    
    public function show_category() {
      $post = new Post();
      $posts = $post->where('category = ?', array($this->params['category']))->all();
      $this->add('posts',$posts);
    }
    
    public function feed_category() {
      $post = new Post();
      $posts = $post->where('category = ?', array($this->params['category']))->all();
      $this->add('posts',$posts);
    }
    
  }
?>

Usando scopes isso não ocorre, veja como ficaría esse exemplo usando scopes.

<?php
  class PostController extends AppController {
    
    public function show_category() {
      $post = new Post();
      $posts = $post->category($this->params['category'])->all();
      $this->add('posts',$posts);
    }
    
    public function feed_category() {
      $post = new Post();
      $posts = $post->category($this->params['category'])->all();
      $this->add('posts',$posts);
    }
    
  }
?>

e no model ficaria assim:

<?php
  class Post extends DrumonModel {
    public $table_name = 'posts';
    
    public function category($category) {
      return $this->where('category = ?',array($category));
    }
    
  }
?>

Dessa maneira o código da aplicação fica mas legível e com melhor mantenabilidade, já que se for necessário alterar a consulta será preciso somente alterar no scope que foi criado no model e ela se estenderá por toda a aplicação.

<?php
  class Post extends DrumonModel {
    public $table_name = 'posts';
    
    public function category($category) {
      return $this->where('category = ?',array($category))->order('created_at DESC');
    }
    
  }
?>

Scopes encadeados

Scopes também podem ser encadeados melhorando ainda mais a reutilização deles na aplicação.

Exemplo de como pegar os posts de uma determinada categoria que foram publicados.

<?php
  class PostController extends AppController {
    
    public function show_category() {
      $post = new Post();
      // Busca todos os posts da categoria developer que foram publicados
      $posts = $post->category('developer')->published()->all();
      $this->add('posts',$posts);
    }
    
  }
?>
<?php
  class Post extends DrumonModel {
    public $table_name = 'posts';
    
    public function category($category) {
      return $this->where('categoty = ?',array($category));
    }

    public function published() {
      return $this->where('published = 1');
    }
    
  }
?>

Default Scope

Pode ser adicionado um scope padrão em determinado model para que todas as consultas feitas nesse modelo tenha um scope padrão.

<?php
  class PostController extends AppController {
    
    public function show_category() {
      $post = new Post();
      // Busca todos os posts da categoria developer que foram publicados
      $posts = $post->category('developer')->all();
      $this->add('posts',$posts);
    }
    
  }
?>
<?php
  class Post extends DrumonModel {
    public $table_name = 'posts';
    
    public function default_scope() {
      return $this->published();
    }
    
    public function category($category) {
      return $this->where('categoty = ?',array($category));
    }

    public function published() {
      return $this->where('published = 1');
    }
    
  }
?>

Clone this wiki locally