-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: return correct changeset params when foreign key is set
- Loading branch information
Showing
3 changed files
with
99 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
## Designing your Context | ||
|
||
Let's talk about how we write our context. | ||
|
||
### When in doubt, sort it out. | ||
|
||
You should never rely on internal implementation details of the underlying stdlib as they may change without notice. When you insert a `has-many` or `many-to-many` association using `Ecto.Changeset.cast_assoc/2` the order of the values returned are not guaranteed to be in the same order as the values inserted. This means we need to sort the data after insertion, Let's look at an example: | ||
|
||
```elixir | ||
defmodule FactoryExExampleTest do | ||
use FactoryEx.DataCase, async: true | ||
|
||
def find_admin_user_account(users), do: Enum.filter(users, &user_account_is_admin?/1) | ||
def all_non_admin_user_accounts(users), do: Enum.reject(users, &user_account_is_admin?/1) | ||
def user_account_is_admin?(user), do: user.account.admin === true | ||
|
||
def create_company_users_accounts(_context) do | ||
# Create 3 Users. Each User Requires an account. One user will have an admin | ||
# account and the other has regular user privileges. | ||
users_params = [ | ||
%{account: %{admin: true}}, | ||
%{}, | ||
%{} | ||
] | ||
# Create a company with 3 users | ||
company_params = %{ | ||
name: "example_company_name", | ||
users: users_params | ||
} | ||
|
||
# These fields will have their appropriate Ecto.Schema | ||
# factory module's build function called. | ||
relational_fields = [ | ||
users: [:account] | ||
] | ||
|
||
# set `validate` to false as the changeset requires an ID and we're making | ||
# an insert so id does not exist. This is used to bypass the changeset behaviour. | ||
company = FactoryEx.build(SchemasPg.Support.Factory.Accounts.Company, company_params, relational: relational_fields, validate: false) | ||
|
||
# Sort and create the context for tests | ||
users = company.users | ||
|
||
user_account_admin = find_admin_user_account(users) | ||
[user_account_one, user_account_two] = all_non_admin_user_accounts(users) | ||
|
||
%{ | ||
company: company, | ||
user_account_admin: user_account_admin, | ||
user_account_one: user_account_one, | ||
user_account_two: user_account_two | ||
} | ||
end | ||
|
||
setup [:create_company_users_accounts] | ||
|
||
test "outputs context result", context do | ||
IO.inspect(context, label: "hooray!") | ||
end | ||
end | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
defmodule FactoryEx.DataCase do | ||
@moduledoc false | ||
use ExUnit.CaseTemplate | ||
|
||
using do | ||
quote do | ||
alias FactoryEx.Support.Repo | ||
|
||
import Ecto | ||
import Ecto.Changeset | ||
import Ecto.Query | ||
import FactoryEx.DataCase | ||
end | ||
end | ||
|
||
setup tags do | ||
:ok = Ecto.Adapters.SQL.Sandbox.checkout(FactoryEx.Support.Repo) | ||
|
||
unless tags[:async] do | ||
Ecto.Adapters.SQL.Sandbox.mode(FactoryEx.Support.Repo, {:shared, self()}) | ||
end | ||
|
||
:ok | ||
end | ||
end |