How to create a resource with the custom generator
Phoenix has some generators built in. But in my opinion, they can be improved. Especially when it is used with the SAAS Starter Kit. So, the SAAS Starter Kit comes with a generator designed to save time, especially when you generate a resource that belongs to another resource.
The resource generator is based on the phx.gen.live generator that comes with Phoenix but has some improvements:
- It handles
belongs_to
out of the box without manual code modifications - It generates admin CRUD as well as the normal LiveView CRUD
- You can make resources account-scoped so it supports multi-tenancy
When you generate and download a SAAS Starter Kit, you also get an key for the resource generator. The actual key is located in the.env
-file and you can update it on https://livesaaskit.com/my
# config/config.exs
config :saas_kit,
admin: true,
api_key: System.get_env("SAAS_KIT_API_KEY")
NOTE, if you picked the admin-option as well when you downloaded the Starter Kit, it will have the optionadmin: true
set as well.
Generate the Resource
In the first example, I want to generate a Posts resource. A post doesnt belong to anyone.
mix saaskit.gen.resource Posts Post posts title content:text published:boolean
When I type the command and press enter, I am prompted with a question:
I need to answer if this belongs to an account. That is the multi tenancy feature that comes with the boilerplate. Since posts does not belongs to a specific account, I will just go ahead and press n.
Next, I get prompted with if this should have a LiveView interface. If I press Y, it will generate the LiveView CRUD that is not under admin.
In this, I don't plan to have a CRUD that is public for all users, so once again, I press n.
Last question that I get prompted with is if I want an admin interface. I think its a good idea to press Y because I to plan to write the posts from the admin interface.
Pressing Y means that the generator goes ahread and generates the following files and also outputs the relevant routes that you can copy paste into your routes file.
Generate a resource the belongs to a another resource
In this scenario, I want to create a resource that belongs to a user.It will be a Todo that belongs to a user. And the command for generating this is:
mix saaskit.gen.resource Todos Todo todos name completed:boolean user_id:references:users
Note, that i have appended user_id:references:users
That means that it will add a user_id field that has a database reference to users table. What it also does, is modifying the code to reflect this relationship.
So, when I press enter, I get propted with this question:
And as you can see, this is not correct. No, when I press n, I get promped with a new question:
This is correct and I can go ahead and press Y. However, if I would have presses no, I would be prompted with filling in the contect and schema myself.
When the files are generated, I can open up and inspect then.
For example, the schema file:
# lib/screen_builder/todos/todo.ex
schema "todos" do
field :completed, :boolean
field :name, :string
belongs_to :user, ScreenBuilder.Users.User # <- This is autoadded
timestamps()
end
Same thing is reflected in the context file with the CRUD functions. One example are the list_todos
# lib/screen_builder/todos.ex
def list_todos(user) do
Repo.all(from u in Todo, where: u.user_id == ^user.id)
end
This is the same for get_todo! and create_todo. And also, same type of modifications for the tests.
When I run all tests, they pass out if the box