Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a UI to allow people to interact with the example? #17

Open
7 tasks
nelsonic opened this issue Dec 10, 2018 · 9 comments
Open
7 tasks

Create a UI to allow people to interact with the example? #17

nelsonic opened this issue Dec 10, 2018 · 9 comments
Labels
discuss enhancement New feature or request help wanted Extra attention is needed in-progress question Further information is requested T1d technical

Comments

@nelsonic
Copy link
Member

nelsonic commented Dec 10, 2018

Reading the example/tutorial code is nice, 👍
but I feel that having an example app on Heroku would be much more beginner-friendly. 🤔
Who wants to make this happen? :-)

Example: https://github.com/dwyl/phoenix-chat-example

Todo

  • Create a basic Form for interacting with the Address Book
    • The form should allow new records to be created
    • Should allow existing records to be "updated" (append only of course)
  • The List of Addresses should be the default "show" view
    • List should be ordered alphabetically by name. (should this be first or last name?)
  • Display the number of revisions for each address as a counter
  • clicking the counter (number) should display the version history for that record.
@nelsonic nelsonic added enhancement New feature or request help wanted Extra attention is needed question Further information is requested discuss technical labels Dec 10, 2018
@nelsonic
Copy link
Member Author

nelsonic commented Apr 23, 2019

The reason I think that this example is highly relevant and useful both to us (@dwyl) and to anyone else wanting to understand both the "Why?" and "How?" of append-only (accountable) application architecture is that having a simple example without any dependencies makes it clear how everything works.

I'm going to make a stab at the todo list above.
I will log my progress as I go and create a PR once there is something to review.

Edit: To be clear: the reason I think this is worth doing first is to understand the "alog" problem from "first principals" before attempting to generalise the solution in github.com/dwyl/alog
Hopefully others will follow my logic here. 🌈

@nelsonic
Copy link
Member Author

Going to try and use mix phx.gen.html command to generate the HTML (form) for the address book:
https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Html.html

Take the mix phx.gen.schema Address command as the basis and adapt it for gen.html

mix phx.gen.schema Address addresses name:string address_line_1:string address_line_2:string city:string postcode:string tel:string

Gen HTML:

mix phx.gen.html Address addresses name:string address_line_1:string address_line_2:string city:string postcode:string tel:string

Got the following error:

** (Mix) Expected the schema, "addresses", to be a valid module name

mix phx.gen.html, phx.gen.json and phx.gen.context expect a
context module name, followed by singular and plural names of
the generated resource, ending with any number of attributes.
For example:

    mix phx.gen.html Accounts User users name:string
    mix phx.gen.json Accounts User users name:string
    mix phx.gen.context Accounts User users name:string

The context serves as the API boundary for the given resource.
Multiple resources may belong to a context and a resource may be
split over distinct contexts (such as Accounts.User and Payments.User).

In my own "throw away" example: https://github.com/nelsonic/append-only-log-ex
I'm going to try deleting the schema and re-creating it using the gen.html command:

mix ecto.drop && MIX_ENV=test mix ecto.drop

You should expect to see:

The database for Append.Repo has been dropped
The database for Append.Repo has been dropped

Try running the Gen HTML command again:

mix phx.gen.html Address addresses name:string address_line_1:string address_line_2:string city:string postcode:string tel:string

That failed because the address.ex file already exists.
Deleting the file: /append-only-log-ex/lib/append/address.ex
Also deleting the migrations:
image

After deleting the files, let's attempt to run the gen.html command again:

mix phx.gen.html Address addresses name:string address_line_1:string address_line_2:string city:string postcode:string tel:string

Derp, we need to add the context! Error message:

** (Mix) Expected the schema, "addresses", to be a valid module name

mix phx.gen.html, phx.gen.json and phx.gen.context expect a
context module name, followed by singular and plural names of
the generated resource, ending with any number of attributes.
For example:

    mix phx.gen.html Accounts User users name:string
    mix phx.gen.json Accounts User users name:string
    mix phx.gen.context Accounts User users name:string

The context serves as the API boundary for the given resource.
Multiple resources may belong to a context and a resource may be
split over distinct contexts (such as Accounts.User and Payments.User).

Add the "Accounts" context to the the gen.html command and run it again:

mix phx.gen.html Accounts Address addresses name:string address_line_1:string address_line_2:string city:string postcode:string tel:string

This time it worked: 🎉

* creating lib/append_web/controllers/address_controller.ex
* creating lib/append_web/templates/address/edit.html.eex
* creating lib/append_web/templates/address/form.html.eex
* creating lib/append_web/templates/address/index.html.eex
* creating lib/append_web/templates/address/new.html.eex
* creating lib/append_web/templates/address/show.html.eex
* creating lib/append_web/views/address_view.ex
* creating test/append_web/controllers/address_controller_test.exs
* creating lib/append/accounts/address.ex
* creating priv/repo/migrations/20190425093946_create_addresses.exs
* creating lib/append/accounts.ex
* injecting lib/append/accounts.ex
* creating test/append/accounts/accounts_test.exs
* injecting test/append/accounts/accounts_test.exs

Add the resource to your browser scope in lib/append_web/router.ex:

    resources "/addresses", AddressController


Remember to update your repository by running migrations:

    $ mix ecto.migrate

@nelsonic
Copy link
Member Author

Going to follow the instructions given after running the gen.html command:
open the lib/append_web/router.ex file and add

    resources "/addresses", AddressController

Update your repository by running migrations:

$ mix ecto.migrate

Fails:

[error] Postgrex.Protocol (#PID<0.301.0>) failed to connect: ** (Postgrex.Error) FATAL 3D000 (invalid_catalog_name) database "append_dev" does not exist
[error] Postgrex.Protocol (#PID<0.300.0>) failed to connect: ** (Postgrex.Error) FATAL 3D000 (invalid_catalog_name) database "append_dev" does not exist
[error] Postgrex.Protocol (#PID<0.301.0>) failed to connect: ** (Postgrex.Error) FATAL 3D000 (invalid_catalog_name) database "append_dev" does not exist
[error] Could not create schema migrations table. This error usually happens due to the following:

  * The database does not exist
  * The "schema_migrations" table, which Ecto uses for managing
    migrations, was defined by another library

To fix the first issue, run "mix ecto.create".

To address the second, you can run "mix ecto.drop" followed by
"mix ecto.create". Alternatively you may configure Ecto to use
another table for managing migrations:

    config :append, Append.Repo,
      migration_source: "some_other_table_for_schema_migrations"

The full error report is shown below.

Run the drop command:

mix ecto.drop && MIX_ENV=test mix ecto.drop

Then run the migrate command again:

mix ecto.create
mix ecto.migrate

Output: (success)

[info] == Running 20190425093946 Append.Repo.Migrations.CreateAddresses.change/0 forward
[info] create table addresses
[info] == Migrated 20190425093946 in 0.0s

Run the mix phx.server command to start the server:

mix phx.server

Visit the app in the browser: http://localhost:4000/addresses
image

@nelsonic
Copy link
Member Author

With the addition of the Accounts context the address.ex schema is now in: /lib/append/accounts/address.ex so that's where we need to make our timestamp change in step 2 of the tutorial.

Now we can run the migrate:

mix ecto.migrate

Output:

Compiling 1 file (.ex)
[info] == Running 20190425093946 Append.Repo.Migrations.CreateAddresses.change/0 forward
[info] create table addresses
[info] execute "REVOKE UPDATE, DELETE ON TABLE addresses FROM append_only"
[info] == Migrated 20190425093946 in 0.0s

@nelsonic
Copy link
Member Author

Run the app mix phx.server
Visit http://localhost:4000/addresses/new
image

Totes works!
image

Now attempt to edit the address: http://localhost:4000/addresses/1/edit
image

Fails because we revoked the UPDATE privileges in our migration (above):
image

@nelsonic
Copy link
Member Author

The question we have to ask ourselves now is: are we going to use the default phoenix auto-incrementing id (in the above case 1) for the id for records. That will always result in errors.

@nelsonic
Copy link
Member Author

in the /test/append/address_test.exs we need to change the line:

alias Append.Address

To:

alias Append.Accounts.Address

@nelsonic
Copy link
Member Author

No changes were required to the lib/append/append_only_log.ex
section of the existing tutorial
we just had to open the file /lib/append/accounts/address.ex add the line:

  use Append.AppendOnlyLog #include the functions from this module's '__using__' macro.

First test passes:
image

In the tutorial, remember to change all instances of Append.Address to Append.Accounts.Address

Remember to link to the issue discussing merits of macros: #8

@nelsonic
Copy link
Member Author

Minor detour (SPIKE) to investigate storing history of a record: dwyl/ecto-postgres-pubsub-spike#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss enhancement New feature or request help wanted Extra attention is needed in-progress question Further information is requested T1d technical
Projects
None yet
Development

No branches or pull requests

1 participant