
O que é o Eloquent ORM?
O Eloquent ORM é distribuído com o framework Laravel para trabalhares com a base de dados de forma simples e sem complicações. Algumas das funcionalidades que lhe deram fama são o soft delete, os timestamps, a implementação de Active Record, a gestão de várias bases de dados, o eager loading, os observers de modelo, os eventos de modelo e muitas outras. As relações do Eloquent são simplesmente métodos das classes de modelo. Definidas como métodos, tornam-se query builders poderosos: podes encadear chamadas e construir consultas muito expressivas.
Como funciona o Eloquent ORM?
O Eloquent ORM é conhecido pela sua implementação de Active Record para trabalhar com bases de dados. O Active Record é um padrão de arquitetura em que cada modelo da arquitetura MVC corresponde a uma tabela da base de dados. Com o Eloquent, crias facilmente dados relacionados na tua base de dados e trabalhas com eles através de um modelo orientado a objetos. Escrever consultas SQL à mão é fastidioso e consome muito tempo. O Laravel Eloquent deixa-te realizar as operações habituais sem longas instruções SQL. Os modelos tornaram triviais a inserção, a atualização, a eliminação e a sincronização entre várias bases de dados. Basta definires as tabelas e a relação entre elas, e está feito.
Começar com o Eloquent
O Laravel traz uma interface de linha de comandos integrada, a consola Artisan. Construída sobre o componente Console do Symfony, dá-te uma forma cómoda de trabalhar a partir do terminal durante a fase de desenvolvimento.
Antes de avançares neste artigo, configura a ligação à base de dados no ficheiro config/database.php.
Antes de começares a usar um modelo Eloquent, verifica se tens o Laravel instalado. Se não tiveres, podes descarregá-lo em getcomposer.org
Para veres a lista de comandos disponíveis no Artisan, escreve o seguinte:
php artisan listTodos os comandos aparecem então no ecrã com uma descrição curta. Se precisares de ajuda sobre um deles, escreve o comando precedido de «help». Por exemplo:
php artisan help migrateCriar modelos Eloquent
Antes de mais, precisas de um modelo para a tua tabela. Os modelos ajudam-te nos seeders, nas factories e no resto. É o modelo que comunica com a base de dados: permite-te consultar as tuas tabelas e povoá-las com dados. Os modelos são normalmente guardados em App\Models apenas por uma questão de código bem documentado. Também preferimos essa convenção, mas a escolha é inteiramente tua, a única exigência é que a classe seja carregada automaticamente segundo o teu ficheiro composer.json. Todos os modelos Eloquent estendem a classe Illuminate\Database\Eloquent\Model. O comando de base para criar modelos é o `make:model` do Artisan:
php artisan make: model StudentA sintaxe de base para definir um modelo é:
class User extends Model {}A migração da base de dados também pode ser gerada ao mesmo tempo que o modelo, bastando acrescentar `-m` ou `-migration` ao comando anterior.
php artisan make:model Student--migration
php artisan make:model Flight -mSeeders, factories, controladores e vários outros tipos de classes podem ser gerados passando as opções certas ao comando Artisan `make:model`. Aqui ficam alguns exemplos:
php artisan make:model Flight --factory
php artisan make:model Flight -f
php artisan make:model Flight --seed
php artisan make:model Flight -s
php artisan make:model Flight --controller
php artisan make:model Flight -cEstas opções também podem ser combinadas para criar várias classes de uma só vez.
php artisan make:model Flight -mfscAlgumas convenções de modelo a ter em mente:
- Nome da tabela: por convenção, os nomes de tabela escrevem-se em minúsculas e no plural, seja qual for a base de dados. Por exemplo, se o modelo se chama Student então a tabela deve chamar-se students. Se o nome do modelo tiver várias palavras, separa-as com underscores.
- Chave primária: o Eloquent parte do princípio de que a chave primária é o atributo id. Podes substituir esse comportamento com `$primaryKey`.
- Timestamps: por omissão, `created_at` e `updated_at` são geridos automaticamente pelo Eloquent. Se preferires tratar deles à mão, põe `$timestamp` a false. Para personalizares o formato de data e hora, usa a propriedade `$dateFormat` do teu modelo.
Atualizar e apagar registos
Atualizar
Para atualizares um modelo, vai buscá-lo, altera o atributo que queres mudar e chama o método save. A coluna `updated_at` é atualizada automaticamente, por isso não precisas de lhe tocar.
$student = Student::find(1);
$student->email = ‘xyz@example.com';
$student>save();As atualizações em massa também podem ser feitas sobre todos os modelos que correspondem a uma dada consulta.
Apagar um modelo existente
Para apagares um modelo, basta chamar o método delete:
$student = Student::find(1);
$student>delete();Apagar pela chave:
Student::destroy(1);
Student::destroy([1, 2, 3]);
Student::destroy(1, 2, 3);Também podes apagar com base numa consulta.
$affectedRows = Student::where('votes', '>', 100)->delete();Modelos relacionados
Qualquer base de dados pode conter modelos relacionados. Quando dois ou mais modelos dependem uns dos outros para os seus valores, chamam-se modelos relacionados. Por exemplo, para acrescentares um novo comentário a um artigo, em vez de preencheres o post_id à mão, podes guardar o comentário diretamente a partir do seu modelo pai
$comment = new Comment(['message' => 'A new comment.']);
$post = Post::find(1);
$comment = $post->comments()->save($comment);Associar modelos
Estes modelos também podem ser atualizados com o método associate, que define uma chave estrangeira no modelo. Podes ainda associar modelos através de várias relações.
Eventos de modelo
Sempre que queres intervir nas etapas do ciclo de vida de um modelo, como a gravação, a atualização ou a eliminação, é disparado um evento: é o evento de modelo. Os eventos disponíveis são saving, saved, deleting, deleted, updating, updated, restoring e restored. Por exemplo, inserir um registo novo dispara o evento creating/created, enquanto um registo que já existe dispara o evento updating/updated.
Cancelar a gravação a partir de um evento
Se o evento devolver false, a ação é cancelada. Serve qualquer evento: deleting, updating, creating, e por aí adiante.
Student::creating(function($student)
{
if ( ! $student>isValid()) return false;
});Como registar listeners de eventos
Como em qualquer linguagem, um evento precisa de um service provider para ser registado, e com os listeners passa-se o mesmo. O Laravel traz o EventServiceProvider que serve de sítio para registares os teus bindings de eventos de modelo.
Por exemplo:
public function boot(DispatcherContract $events)
{
parent::boot($events);
Student::creating(function($student)
{
//
});
}Observers de modelo
Os observers de modelo ajudam-te a tratar os eventos de modelo. Uma classe de observer pode ter um método por cada evento de modelo.
class StudentObserver {
public function saving($model)
{
//
}
public function saved($model)
{
//
}
}Outra forma de registar um observer é através do método observe
User::observe(new UserObserver);Gerar URLs de modelo
Os URLs de modelo dão-te o URL de um registo único, bastando passar o modelo ao helper route ou action. Quando um modelo é passado a route ou a action, a sua chave primária é inserida no URI.
Route::get('student/{student}', 'StudentController@show');
action('StudentController@show', [$student]);Aqui, o id do estudante é inserido no URL. Se quiseres usar outra propriedade no URL gerado, tens de substituir o método getRouteKey no teu modelo.
public function getRouteKey()
{
return $this->slug;
}Mais sobre as funcionalidades do Laravel Eloquent
Converter em arrays e JSON
Quando constróis uma API, a resposta é quase sempre em JSON, o que te obriga a transformar os teus modelos e as suas relações em JSON ou em arrays. O Laravel Eloquent também responde a essa necessidade. Para converteres um modelo e as suas relações num array, usa o método toArray().
$student = Student::with('roles')->first();
return $student->toArray();Para converteres um modelo em JSON, podes usar o método seguinte:
return Student::find(1)->toJson();Vejamos agora como devolver um modelo a partir de uma rota. Sempre que um modelo é convertido em string, passa a JSON, por isso podes devolver objetos Eloquent diretamente a partir das tuas rotas.
Route::get('student', function()
{
return Student::all();
});Alguns valores protegidos, como `personal_id` ou a palavra-passe, devem ficar escondidos. Para isso, acrescenta `$hidden` ao teu modelo,
Casting de atributos
Se queres mudar o tipo de dados de um atributo, uma opção é escrever um mutator para cada um deles, o que demora tempo e convida a erros. A outra opção é fazer o cast do atributo em questão: acrescenta-o à propriedade casts do teu modelo. Os outros tipos de cast aceites são integer, float, double, real, object, string, array.
Aqui fica um exemplo.
protected $casts = [
'is_student' => 'boolean',
];Neste exemplo, mesmo que is_student esteja guardado com outro tipo de dados, ao lê-lo obténs sempre um boolean.
O cast em array é muito prático quando trabalhas com uma coluna que guarda JSON serializado. JSON serializado significa apenas um objeto codificado numa string. Se uma das tuas colunas contém JSON serializado, o cast em array converte-o automaticamente num array PHP assim que o lês a partir do teu modelo Eloquent.
protected $casts = [
'options' => 'array',
];Mutators de data
O Carbon é uma extensão internacional do DateTime do PHP. O Eloquent converte created_at e updated_at em instâncias de Carbon, que estendem a classe DateTime do PHP e acrescentam vários métodos úteis. Personalizar isto é fácil se não quiseres a mutação automática: basta substituíres o método getDates na tua classe. Para desativares completamente a mutação de datas, devolve um array vazio no método `getDates` desta classe. Aqui fica um exemplo:
public function getDates()
{
return ['created_at'];
}Quando uma coluna é tratada como data, tens quatro possibilidades para o seu valor: um timestamp UNIX, uma string de data (Y-m-d), uma data-hora ou uma instância de DateTime/Carbon.
Accessors e mutators
Tal como ler e escrever valores em qualquer linguagem, os accessors e os mutators permitem-te formatar os atributos Eloquent antes de os ler ou de os escrever nas instâncias do modelo. A diferença entre os dois é que os accessors servem para ler os dados, enquanto os mutators são responsáveis por os alterar.
Para definires um accessor, declara `getFooAttribute` no teu modelo, o nome do método tem de estar em camel case, quer o nome da coluna esteja em minúsculas ou não.
class User extends Model {
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}Um mutator define-se da mesma forma: usa `setFooAttribute` e sim, o camel case também se aplica aqui.
class User extends Model {
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}Soft deletes
Um soft delete não apaga a linha da base de dados, escreve um timestamp à parte. Uma coluna `deleted_at` é preenchida no registo correspondente. Podes fazer soft delete no teu modelo aplicando-lhe o trait SoftDeletes.
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
}softDeletes() serve para acrescentar a coluna deleted_at na migração. Uma migração não é mais do que gerir a tua base de dados em PHP em vez de SQL.
$table->softDeletes();Nalguns casos vais querer que as linhas em soft delete apareçam nos resultados de uma consulta. Para isso, usa o withTrashed() na consulta.
Para mostrares apenas os modelos em soft delete nos resultados, usa o método onlyTrashed() na consulta.
$student = Student::onlyTrashed()->where('account_id', 1)->get();Depois de todas estas operações, se quiseres repor os modelos em soft delete no ativo, chama o método restore no modelo.
$student->restore();restore() também pode ser usado diretamente na consulta.
Student::withTrashed()->where('account_id', 1)->restore();Agora, depois de um soft delete, se quiseres apagar o modelo da base de dados de vez, usa o forceDelete() no modelo.
$student->posts()->forceDelete();Para verificares se um modelo foi apagado ou não, podes usar o método trashed().
if ($student->trashed())
{
//Todo
}Conclusão
O Laravel é um dos frameworks PHP mais conhecidos, e o Laravel Eloquent dá-te uma forma muito simples de comunicar com as tuas bases de dados. Neste artigo cobrimos algumas das funcionalidades importantes do Eloquent. Há muitas mais, e podes lê-las aqui. Segue a ligação e descobre tudo o que o Laravel Eloquent sabe fazer.


