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:
belongs_to
out of the box without manual code modifications
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.
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.
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