Can't create new entry in database

I would expect this to work with the --no-html flag, but it’s not working for me either. However, without the --no-html flag, and running mix ecto.create before migrating works

Did you do this, it’s part of the output after generating the new project:

Add the resource to your :api scope in lib/book_list_web/router.ex:

resources "/users", UserController, except: [:new, :edit]

In your current project the /api scope is commented out. But even if it wasn’t there would be no entry for the User schema.

You just need to uncomment the /api scope and add the entry. The user_path/3 function is path helper so it’s trying to return a path based on a route definition which doesn’t exist in this scenario.

Here’s a link to some information on path helpers.
https://hexdocs.pm/phoenix/routing.html#path-helpers

Hope that helps
Paul

2 Likes

Thank you all !!

The solution: (1) Use the phx prefix consistently – no mixing with phoenix; (2) The phx generators require a context module name before the model module name and its lowercase plural; (3) You have to add the route, as @paulsullivanjr noted – this is not done automatically.

All working now; I very much appreciate everyone’s help.

1 Like

I’d go as far as saying forget about models (essentially what phx does by shifting from mix phoenix.gen.model to mix phx.gen.schema).

mix phx.gen.context is largely a convenience tool rather than a prescription for contexts:

mix phx.gen.context Accounts User users name:string age:integer

simply creates the persisted User data type inside the Accounts context (which is created if it doesn’t already exist). The generator doesn’t convey that

  • a single context can have multiple persisted data types
  • the type persisted may not be the type that is shared through the module API because the persisted type may contain details that are appropriate for internal context use only.

In the simplest terms “model” has a habit of putting the data type persisted as a table front and center based on an oversimplified “wiring” of resource based Server MVC:

GET resource/:id    → SELECT * FROM resource WHERE id = :id
POST resource       → INSERT INTO resource 
PUT resource/:id    → UPDATE resource WHERE id = :id
DELETE resource/:id → DELETE resource WHERE id = :id

The CRUD oversimplification isn’t what REpresentational State Transfer is all about. For example creating a “money transfer resource” could be responsible updating the two accounts represented in the state of the resource.

In contrast to “model” the context is supposed to put related behaviour front and center - at the same time giving the context autonomy over its internal data types and how they are persisted. So an E-commerce site could have Sales, Billing, Shipping contexts while Sales and Shipping each have their own internal Product type (collaborating via some common Product Key or public (non-persisted) Product type). And contexts aren’t about REST resources - they deal with domain types and their behaviours.

1 Like

Thank you very much. This is a great help!

I should note however that even Programming Phoenix ≥ 1.4 still advocates this implementation of “Phoenix MVC”:

48%20PM

The “model” is the collection of persisted data types, the associated queries, and changesets - but without Repo access. This is justified by striving to keep everything inside the “model” free from side effects, leaving it ultimately up to the controller to effect changes in persisted state by pushing the built-up changesets into the appropriate Repo functions.

This is in contrast to the typical understanding of a bounded context which puts a boundary around its internal types (and associated transformations usually implemented in a persistence-ignorant manner with direct access to/on top of a Repository)

(Edit: some of the Programming Phoenix ≥ 1.4 code actually looks less like the above graphic as context functions will access the Ecto repo themselves - in which case side effects are accepted in order to keep implementation details out of the controller)

“Phoenix MVC” is the basis of Dave Thomas’s claim that:

first 1.2 and then 1.3 actually tightened the coupling between the two.

[i.e. Phoenix and Ecto] - making a case for removing the database (and Ecto) entirely out of Phoenix and using them inside a separate OTP component (OTP application) which exposes an API to which Phoenix connects.

28%20PM

2 Likes