# `Bylaw.Ecto.Query.Checks.ManualJoinInsteadOfAssoc`
[🔗](https://github.com/ryanzidago/bylaw/blob/v0.1.0-alpha.1/lib/bylaw/ecto/query/checks/manual_join_instead_of_assoc.ex#L1)

Validates that manual joins use `assoc/2` when a root association exists.

This check catches direct schema joins that spell out a relationship already
declared on the query root schema.

## Examples

Bad:

    from(Post, as: :post)
    |> join(:inner, [post: p], c in Comment,
      as: :comment,
      on: c.post_id == p.id
    )

Why this is bad:

When `Post` defines `has_many :comments, Comment`, the query reimplements
association metadata by hand. Future association changes can drift away from
the manual join.

Better:

    from(Post, as: :post)
    |> join(:inner, [post: p], c in assoc(p, :comments),
      as: :comment
    )

Why this is better:

Ecto uses the association metadata for keys, through joins, preloads, and
future schema changes.

## Notes

This check only rejects direct schema joins when the root schema declares a
matching association. It ignores reverse-only associations and joins that are
already written with `assoc/2`.

Association joins let Ecto use the association metadata for foreign keys,
through joins, preloads, and future schema changes. Manual joins are only
rejected when the joined source is an Ecto schema module and the root schema
defines an association whose related schema matches it.

## Options

  * `:validate` - explicit `false` disables the check. Defaults to `true`.

This check intentionally looks at associations defined on the root schema,
because those are the associations that can be used as `assoc(root, name)` in
the query. Reverse-only associations on the joined schema are ignored.

## Usage

Add this module to the explicit check list passed through `Bylaw.Ecto.Query`.
See `Bylaw.Ecto.Query` for the full `c:Ecto.Repo.prepare_query/3` setup.

# `validate`

```elixir
@spec validate(
  Bylaw.Ecto.Query.Check.operation(),
  Bylaw.Ecto.Query.Check.query(),
  opts()
) ::
  Bylaw.Ecto.Query.Check.result()
```

Implements the `Bylaw.Ecto.Query.Check` validation callback.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
