{"id":25982689,"url":"https://github.com/combizera/laravel-relationships-guide","last_synced_at":"2025-03-05T09:40:11.321Z","repository":{"id":260514506,"uuid":"881512537","full_name":"combizera/laravel-relationships-guide","owner":"combizera","description":"Guia prático de relacionamentos no Laravel com exemplos e boas práticas para facilitar o desenvolvimento.","archived":false,"fork":false,"pushed_at":"2024-11-30T20:17:10.000Z","size":10597,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"guide","last_synced_at":"2024-11-30T21:22:02.740Z","etag":null,"topics":["backend","guide","laravel","polymorphism","relationships"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/combizera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-31T18:11:56.000Z","updated_at":"2024-11-30T20:17:13.000Z","dependencies_parsed_at":"2024-11-07T11:23:28.549Z","dependency_job_id":null,"html_url":"https://github.com/combizera/laravel-relationships-guide","commit_stats":null,"previous_names":["combizera/relationship","combizera/laravel-relationships-guide"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/combizera%2Flaravel-relationships-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/combizera%2Flaravel-relationships-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/combizera%2Flaravel-relationships-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/combizera%2Flaravel-relationships-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/combizera","download_url":"https://codeload.github.com/combizera/laravel-relationships-guide/tar.gz/refs/heads/guide","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242003947,"owners_count":20056368,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","guide","laravel","polymorphism","relationships"],"created_at":"2025-03-05T09:40:10.471Z","updated_at":"2025-03-05T09:40:11.272Z","avatar_url":"https://github.com/combizera.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Relacionamentos no Laravel\n\nOs relacionamentos no Laravel são excelentes para gerenciar e trabalhar com associações entre diferentes tabelas do Banco de Dados.\n\nCriei este repositório para documentar e consolidar meus estudos sobre os relacionamentos no Laravel. Como vim do Front-End, logo percebi necessidade de aprofundar meu entendimento em Back-End, especialmente no Laravel. Ter uma compreensão sólida sobre os relacionamentos entre tabelas além de otimizar meu trabalho também garante que as aplicações sejam bem estruturadas, eficientes e escaláveis.\n\nA ideia é que este repositório sirva tanto como uma referência pessoal quanto uma fonte de consulta para outros devs que queiram entender os relacionamentos no Laravel.\n\n## Índice\n\n- [Informações Gerais](#informações-gerais)\n   - [Convenções de Nomenclatura](#convenções-de-nomenclatura)\n\n- [Relacionamentos](#relacionamentos)\n   - [HasOne](#hasone)\n   - [HasMany](#hasmany)\n   - [HasOneOfMany](#hasoneofmany)\n   - [BelongsTo](#belongsto)\n   - [BelongsToMany](#belongstomany)\n   - [HasOneThrough](#hasonethrough)\n   - [HasManyThrough](#hasmanythrough)\n   - [Polimorfismo](#polimorfismo)\n   - [MorphOne](#morphone)\n   - [MorphMany](#morphmany)\n   - [MorphTo](#morphto)\n   - [MorphToMany](#morphtomany)\n\n- [Referências e Recursos](#referências-e-recursos)\n- [Contribuição](#contribuição)\n\n## Informações Gerais\n\n1. Convenções de nomenclatura\n   - No Laravel assumimos que a chave estrangeira (FK) terá o nome do Model em `snake_case` seguido de `_id`. Por exemplo, se temos um Model `User`, a chave estrangeira será `user_id`.\n   - O Laravel também assume que a chave primária (PK) será `id`. Se você deseja usar outro nome para a chave primária, você deve especificar isso no Model.\n   - Em relacionamento polimórficos o Laravel tem por convenção que o nome do método seja o nome da relação seguido de `able`. Por exemplo, se temos um relacionamento polimórfico entre `Comment` e `Post`, o método será `commentable`.\n\n---\n\n## HasOne\n\nO relacionamento `HasOne` (TemUm) é usado quando uma Model possui exatamente uma instância de outra Model. Por exemplo, um usuário **tem um** avatar.\n    \n```php\n// App\\Models\\User.php\npublic function avatar(): HasOne\n{\n    return $this-\u003ehasOne(Avatar::class);\n}\n\n// App\\Models\\Avatar.php\npublic function user(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n```\n\nOu seja, um usuário pode ter *um* avatar e um avatar pertence a um usuário.\n\n---\n\n\n## HasMany\nO relacionamento `HasMany` (TemMuitos) é usado quando uma Model pode ter múltiplas instâncias de outro Model. Por exemplo, um usuário pode ter vários posts.\n\n```php\n// App\\Models\\User.php\npublic function posts(): HasMany\n{\n    return $this-\u003ehasMany(Post::class);\n}\n\n// App\\Models\\Post.php\npublic function user(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n```\n\nOu seja, um usuário pode ter **muitos** posts e um post pertence a um usuário.\n\n---\n\n## HasOneOfMany\n\nO relacionamento `HasOneOfMany` (TemUmDeMuitos) é usado quando uma Model possui exatamente uma instância de outra Model, mas essa Model pode estar associada a várias instâncias da Model pai. A diferença entre `HasOne` e `HasOneOfMany` é que, no `HasOneOfMany`, a instância única é determinada por uma condição ou critério, como o registro mais recente, mais antigo ou com base em outra característica.\n\n### Exemplo\n\nImagine que um usuário pode ter vários endereços, mas queremos identificar o endereço principal com base no campo `is_main`:\n\n```php\n// App\\Models\\User.php\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneOfMany;\n\npublic function mainAddress(): HasOneOfMany\n{\n    return $this-\u003ehasOneOfMany(Address::class, 'user_id')-\u003ewhere('is_main', true);\n}\n\n// App\\Models\\Address.php\npublic function user(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n```\n\nNesse exemplo, o método mainAddress retorna apenas o endereço principal do usuário, baseado na condição `is_main = true`.\n\nUse `HasOneOfMany` sempre que precisar trabalhar com relações que exijam critérios específicos para determinar a instância única do relacionamento.\n\n---\n\n## BelongsTo\n\nO relacionamento `BelongsTo` (PertenceA) é o inverso de `HasOne` e `HasMany`. É usado quando uma Model pertence a outra Model. Por exemplo, um post pertence a um usuário.\n\n```php\n// App\\Models\\Comment.php\npublic function post(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n\n// App\\Models\\Post.php\npublic function comments(): HasMany\n{\n    return $this-\u003ehasMany(Post::class);\n}\n```\n\nOu seja, um comentário pertence a um post e um post pode ter **muitos** comentários.\n\n---\n\n## BelongsToMany\n\nO relacionamento `BelongsToMany` (PertenceAMuitos) é usado quando uma Model pode ter múltiplas instâncias de outra Model e vice-versa. \n\n```php\n// App\\Models\\Student.php\npublic function courses(): BelongsToManypa\n{\n    return $this-\u003ebelongsToMany(\n        // Model que queremos relacionar\n        Course::class, \n        // Nome da tabela intermediária\n        'student_courses'\n    );\n}\n\n// App\\Models\\Course.php\npublic function students(): BelongsToMany\n{\n    return $this-\u003ebelongsToMany(Student::class, 'student_courses');\n}\n```\nOu seja, um estudante pode ter estar matriculado em vários cursos e um curso é capaz de ter vários estudantes matriculados.\n\n---\n\n## HasOneThrough\n\n### Laravel e a DX (Developer Experience)\nO Laravel é conhecido por sua DX (Developer Experience) e por simplificar tarefas complexas. Uma dessas facilidades que temos no processo de codar é a utilização de relacionamentos `HasOneThrough` e `HasManyThrough`. \n\n---\n\nUsamos o `HasOneThrough` (TemUmAtravés) quando queremos acessar um registro que está indiretamente relacionado através de uma `Model` intermediária. Ele é útil quando um Model está a uma \"distância\" de outra tabela, e queremos simplificar o acesso.\n\nPrimeiro fazemos o relacionamento básico entre as Models `User`, `Address` e `Order`:\n```php\n// App\\Models\\User.php\n// Um usuário tem muitos pedidos e um endereço\npublic function orders(): HasMany\n{\n    return $this-\u003ehasMany(Order::class);\n}\n\npublic function address(): HasOne\n{\n    return $this-\u003ehasOne(Address::class);\n}\n\n// App\\Models\\Order.php\n// Um pedido pertence a um usuário\npublic function user(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n\n// App\\Models\\Address.php\n// Um endereço pertence a um usuário\npublic function user(): BelongsTo\n{\n    return $this-\u003ebelongsTo(User::class);\n}\n```\n\nAgora, vamos acessar o endereço de um pedido **através** do usuário. Para isso, vamos criar o método `address` no Model `Order`:\n\n```php\n// App\\Models\\Order.php\n// Um pedido tem um endereço através de um usuário\npublic function address(): HasOneThrough\n{\n    return $this-\u003ehasOneThrough\n    (\n        // O primeiro argumento é a Model que queremos acessar\n        Address::class,\n        // Model intermediária\n        User::class,\n        // Chave estrangeira da Model intermediária\n        'id',\n        // Chave estrangeira da Model que queremos acessar\n        'user_id',\n        // Chave primária da Model que queremos acessar\n        'id',\n    );\n}\n```\n\nOu seja, um pedido tem um endereço **através** de um usuário. Então ao invés de acessar o endereço através do usuário, podemos acessar diretamente pelo pedido.\n\n---\n\n## HasManyThrough\n\nO `HasManyThrough` (TemMuitosAtravés) é semelhante ao `HasOneThrough`, mas ao invés de retornar um único registro, ele retorna uma `Collection` de registros. Neste exemplo vamos utilizar de um exemplo de `College`, que tem muitos `Teacher` e cada `Teacher` tem muitas `Lesson`.\n\nPrimeiro, vamos criar os relacionamentos básicos entre as Models `College`, `Teacher` e `Lesson`:\n\n```php\n// App\\Models\\College.php\n// Uma escola tem muitos professores\npublic function teachers(): HasMany\n{\n    return $this-\u003ehasMany(Teacher::class);\n}\n\n// App\\Models\\Teacher.php\n// Um professor pertence a uma escola e tem muitas aulas\npublic function college(): BelongsTo\n{\n    return $this-\u003ebelongsTo(College::class);\n}\n\npublic function lessons(): HasMany\n{\n    return $this-\u003ehasMany(Lesson::class);\n}\n\n// App\\Models\\Lesson.php\n// Uma aula pertence a um professor\npublic function teacher(): BelongsTo\n{\n    return $this-\u003ebelongsTo(Teacher::class);\n}\n```\n\nAgora, vamos acessar as aulas de uma escola através dos professores. Para isso, vamos criar o método `lessons` no Model `College`:\n\n```php\n// App\\Models\\College.php\npublic function lessons(): HasManyThrough\n{\n    return $this-\u003ehasManyThrough\n    (\n        Lesson::class,\n        Teacher::class,\n        'id',\n        'teacher_id',\n    );\n}\n```\n\nOu seja, uma escola tem muitas aulas **através** de um professor. Ao invés de acessar as aulas através do professor, podemos acessar diretamente pela Model `College`.\n\n---\n\n## Polimorfismo\n\nO polimorfismo é um conceito que permite que um objeto possa ser tratado de várias formas. No Laravel, o polimorfismo é usado para criar relações polimórficas entre Models.\n\nSendo mais didático, imagine que temos uma Model `Comment` que pode ser associada a uma Model `Post` ou a uma Model `Video`. Neste caso, podemos usar o polimorfismo para criar uma relação polimórfica entre `Comment` e `Post` e `Comment` e `Video`.\n\n```php\n// App\\Models\\Comment.php\npublic function commentable(): MorphTo\n{\n    return $this-\u003emorphTo();\n}\n\n// App\\Models\\Post.php\npublic function comments(): MorphMany\n{\n    return $this-\u003emorphMany(Comment::class, 'commentable');\n}\n\n// App\\Models\\Video.php\npublic function comments(): MorphMany\n{\n    return $this-\u003emorphMany(Comment::class, 'commentable');\n}\n```\n\nOu seja, um comentário pode ser associado a um post ou a um vídeo.\n\n_ps: Esse sufixo `able` é uma convenção do Laravel para indicar que a Model é polimórfica. No exemplo dado, `commentable` é o método que define a relação polimórfica._ \n\nIsto posto, vamos falar agora sobre as relações polimórficas disponíveis no Laravel:\n\n---\n\n## MorphOne\n\nO relacionamento `MorphOne` é usado quando uma Model possui exatamente uma instância de outra Model. Vamos dar o exemplo de uma uma `Image` em um Blog, que pode ser associada a um `Post` ou a uma `Category`.\n\n```php\n// App\\Models\\Image.php\npublic function imageable(): MorphTo\n{\n    return $this-\u003emorphTo();\n}\n\n// App\\Models\\Post.php\npublic function image(): MorphOne\n{\n    return $this-\u003emorphOne(Image::class, 'imageable');\n}\n\n// App\\Models\\Category.php\npublic function image(): MorphOne\n{\n    return $this-\u003emorphOne(Image::class, 'imageable');\n}\n```\n\nDesta forma, definimos que uma imagem pode ser associada a um post ou a uma categoria.\n\n---\n\n## MorphMany\n\nO `MorphMany` é usado quando uma Model pode ter múltiplas instâncias de outra Model. Por exemplo um `Comment` que pode ser associada a um `Post` ou a uma `Video`.\n\n```php\n// App\\Models\\Comment.php\npublic function commentable(): MorphTo\n{\n    return $this-\u003emorphTo();\n}\n\n// App\\Models\\Post.php\npublic function comments(): MorphMany\n{\n    return $this-\u003emorphMany(Comment::class, 'commentable');\n}\n\n// App\\Models\\Video.php\npublic function comments(): MorphMany\n{\n    return $this-\u003emorphMany(Comment::class, 'commentable');\n}\n```\n\nDesta forma, definimos que um comentário pode ser associado a um `Post` ou a um `Video`.\n\n---\n\n## MorphTo\n\nO relacionamento `MorphTo` é usado quando uma Model pode pertencer a uma de várias Models. Vamos dar o exemplo de uma `Image` que pode pertencer a um `Post` ou a uma `Category`.\n\n```php\n// App\\Models\\Image.php\npublic function imageable(): MorphTo\n{\n    return $this-\u003emorphTo();\n}\n\n// App\\Models\\Post.php\npublic function image(): MorphOne\n{\n    return $this-\u003emorphOne(Image::class, 'imageable');\n}\n\n// App\\Models\\Category.php\npublic function image(): MorphOne\n{\n    return $this-\u003emorphOne(Image::class, 'imageable');\n}\n```\n\nDesta forma, definimos que uma imagem pode pertencer a um post ou a uma categoria.\n\n---\n\n## MorphToMany\n\nO relacionamento `MorphToMany` é usado quando uma Model pode ter múltiplas instâncias de outra Model e vice-versa. Vamos usar o exemplo clássico de `Tag` que pode ser associada a um `Post` ou a uma `Video`.\n\n```php\n// App\\Models\\Tag.php\npublic function posts(): MorphToMany\n{\n    return $this-\u003emorphedByMany(Post::class, 'taggable');\n}\n\npublic function videos(): MorphToMany\n{\n    return $this-\u003emorphedByMany(Video::class, 'taggable');\n}\n\n// App\\Models\\Post.php\npublic function tags(): MorphToMany\n{\n    return $this-\u003emorphToMany(Tag::class, 'taggable');\n}\n\n// App\\Models\\Video.php\npublic function tags(): MorphToMany\n{\n    return $this-\u003emorphToMany(Tag::class, 'taggable');\n}\n```\n\nDesta forma, definimos que uma tag pode ser associada a um post ou a um vídeo.\n\n---\n\n\n## Referências e Recursos\n\nFiz esse repositório baseado em duas principais fontes para entender e estruturar melhor os relacionamentos no Laravel.\n- [Documentação oficial do Laravel](https://laravel.com/docs/)\n- [Curso de Relacionamentos do Clube Full-Stack](https://www.youtube.com/watch?v=pL_th7hHRxE\u0026list=PLyugqHiq-SKcCjcxq33TGy5i-E3O0lHdv\u0026pp=iAQB)\n\nConsulte essas fontes para um estudo mais aprofundado sobre cada tipo de relacionamento 🫡\n\n## Contribuição\n\nContribuições são bem-vindas! Se você encontrou um erro, tem sugestões de melhoria ou deseja adicionar um novo exemplo, fique à vontade para abrir uma `issue` ou um `pull request`.\n\n### Para contribuir:\n1. Faça um fork do projeto\n2. Crie uma nova branch com sua contribuição (`git checkout -b feat/nome-da-feature`)\n3. Commit suas alterações (`git commit -m 'Descrição da sua contribuição'`)\n4. Faça o push para sua branch (`git push origin feature/nome-da-sua-feature`)\n5. Abra um Pull Request para o repositório original\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcombizera%2Flaravel-relationships-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcombizera%2Flaravel-relationships-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcombizera%2Flaravel-relationships-guide/lists"}