Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/actions/guides/command_line_tasks/built_in.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Guides::CommandLineTasks::BuiltIn < GuideAction
Lucky comes bundled with [LuckyTask](https://github.com/luckyframework/lucky_task) for creating tasks.

Tasks are used to run some code that sits outside of your main application. When you need to add a task, you'll place it in the `tasks` folder.
To see a list of the available tasks in your application, use `lucky --help`.
To see a list of the available tasks in your application, use `lucky tasks`.

You can think of a Luck Task just like a [Rake task](https://github.com/ruby/rake) in Ruby, [npm script](https://docs.npmjs.com/misc/scripts) for Node,
or [Mix Task](https://hexdocs.pm/mix/Mix.Task.html) for Elixir.
Expand All @@ -27,7 +27,7 @@ class Guides::CommandLineTasks::BuiltIn < GuideAction
By default, Lucky has lots of tasks already built in that you may find really handy while developing your application. These are the ones that you get by default.

```plain
# Generated with lucky --help
# Generated with lucky tasks
▸ db.console Access PostgreSQL console
▸ db.create Create the database
▸ db.drop Drop the database
Expand Down
5 changes: 2 additions & 3 deletions src/actions/guides/getting-started/installing.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
class Guides::GettingStarted::Installing < GuideAction
ANCHOR_INSTALL_REQUIRED_DEPENDENCIES = "perma-install-required-dependencies"
ANCHOR_POSTGRESQL = "perma-install-postgres"
ANCHOR_PROC_MANAGER = "perma-install-process-manager"
ANCHOR_NODE = "perma-install-node"
ANCHOR_BUN = "perma-install-bun"
guide_route "/getting-started/installing"

def self.title
Expand Down Expand Up @@ -318,7 +317,7 @@ class Guides::GettingStarted::Installing < GuideAction
postgres=# \\q
```

#{permalink(ANCHOR_NODE)}
#{permalink(ANCHOR_BUN)}
## Bun (optional)

> You can skip this if you only plan to build APIs.
Expand Down
20 changes: 10 additions & 10 deletions src/actions/guides/tutorial/00_overview.cr
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Guides::Tutorial::Overview < GuideAction
* installed Crystal. `crystal -v` should be at least #{LuckyCliVersion.min_compatible_crystal_version} or higher
* installed Lucky. `lucky -v` should be #{LuckyCliVersion.current_tag}.
* installed [Postgres](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_POSTGRESQL)}). `psql --version` should be `>= #{LuckyDependencyVersions.min_compatible_postgres_version}`
* installed [Node](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_NODE)}). `node -v` should be `>= v#{LuckyDependencyVersions.min_compatible_node_version}` (used for building css and javascript)
* installed [Bun](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_BUN)}). `bun -v` should be `>= v#{LuckyDependencyVersions.min_compatible_bun_version}` (used for bundling css and javascript/typescript)

## The Wizard

Expand Down Expand Up @@ -98,22 +98,22 @@ class Guides::Tutorial::Overview < GuideAction

> For more information on setting up your database, read the [Database Setup](#{Guides::Database::DatabaseSetup.path}) guide.

### Setup Script
### Bootstrap Setup

Next we will run our setup script. This script does a few things:
Next we will run our setup script to bootstrap our app. This script does a few things:

* Run a system check for 3rd party dependencies needed to run this app.
* Setup our assets (css, javascript) using Yarn
* Setup our assets (css, javascript) using Bun
* Install Crystal shard dependencies. (e.g. Lucky, Avram, etc...)
* Create our database. In this case, a database named `clover_developement`
* Verify that we can connect to this new database
* Run SQL code (migration) to create our users table.
* Import sample data in to our database. On the first run, there's no sample data.

Run the setup script. Enter `./script/setup`:
Run the setup script. Enter `crystal script/setup.cr`:

```bash
./script/setup
crystal script/setup.cr
```

> This may take a bit of time to run. If anything fails at any point, let us know!
Expand All @@ -136,14 +136,14 @@ class Guides::Tutorial::Overview < GuideAction
## Browsing your Application

Open up your favorite browser, and head over to `http://127.0.0.1:3000`. This URL will be printed
in your terminal log output.
in your terminal log output when the `web` process has booted.

> To change the port your app runs on, update the `port` option in the `config/watch.yml` file.

You should now see the Lucky home page.

Click the "VIEW YOUR NEW APP" button to be taken to a "Sign Up" page. Because the wizard set us up
with Authentication, we now have the ability to create a User account, and log in. Make your account!
Click the "VIEW YOUR NEW APP" button to be taken to a "Sign Up" page. Because the wizard set up
authentication, we now have the ability to create a User account, and log in. Make your account!

After you've signed up, you are taken to your "Profile" page.

Expand All @@ -160,7 +160,7 @@ class Guides::Tutorial::Overview < GuideAction
* Sign back in to your account
* View your terminal to see how each request is logged to the output

> When you're done, stop your server with `ctrl-C` before moving on to the next section.
> When you're done, stop your server with `ctrl-c` before moving on to the next section.

MD
end
Expand Down
7 changes: 5 additions & 2 deletions src/actions/guides/tutorial/01_new_resource.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ class Guides::Tutorial::NewResource < GuideAction
## Using the Generator CLI

Lucky comes with a lot of neat commands to make building your application a little easier.
From your terminal, type `lucky -h`. Give it a moment to compile, then see a list of the commands you can use.
From your terminal, type `lucky -h`. This will display a few commands you can run; one in particular is the `tasks` command.
Now run `lucky tasks` and give it a moment to compile. This will display even more commands you can run.

For our next section, we will be generating a new "resource"; the "Fortune". In this context, a resource is a Model,
> This commands must compile because it includes any custom commands you've added as well as commands added by 3rd party dependencies (shards).

For our next section, we will be generating a new "resource"; the `Fortune`. In this context, a resource is a Model,
Action, Page, Component, Query, and Operation. Lucky breaks a resource down in to smaller class components which we
will discuss over the tutorial.

Expand Down
16 changes: 8 additions & 8 deletions src/actions/guides/tutorial/02_assocations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Guides::Tutorial::Associations < GuideAction
<<-MD
## New Migrations

When we generated our migration, we didn't add a way to tie Fortunes to a specific User. It may be common
When we generated our migration, we didn't add a way to tie Fortunes to a specific `User`. It may be common
that you will need to generate separate migrations to update models that already exist in your application.
Let's try that now.

Expand All @@ -36,7 +36,7 @@ class Guides::Tutorial::Associations < GuideAction
# db/migrations/#{Time.utc.to_s("%Y%m%d%H%I%S")}_add_belongs_to_user_for_fortune.cr

def migrate
# FYI: We will run in to an error. Be sure to keep reading before running any code
# NOTE: We will run into an error. Be sure to keep reading before running any code
alter table_for(Fortune) do
add_belongs_to user : User, on_delete: :cascade, fill_existing_with: :nothing
end
Expand Down Expand Up @@ -112,26 +112,26 @@ class Guides::Tutorial::Associations < GuideAction

At the bottom of the `table` block, we will add this new code:

```diff
```crystal
# src/models/user.cr

table do
column email : String
column encrypted_password : String

+ has_many fortunes : Fortune
has_many fortunes : Fortune # <--- Add this line
end
```

Next we will update our `Fortune` model in `src/models/fortune.cr` with this code:

```diff
```crystal
# src/models/fortune.cr

table do
column text : String

+ belongs_to user : User
belongs_to user : User # <--- Add this line
end
```

Expand All @@ -150,11 +150,11 @@ class Guides::Tutorial::Associations < GuideAction
* Sign in, and try to create a fortune. Notice it fails
* View your logs to see "Failed to save SaveFortune".
* Use `lucky exec` to truncate all `User` records with the `UserQuery` object.
* Pass `user_id: current_user.id` to `SaveFortune.create`
* Then use your app to make a new user record, because we still need one 😄

We will update the forms later in the tutorial.

> Before continuing to the next section, create a new user account. We will need it in the next section.

MD
end
end
61 changes: 24 additions & 37 deletions src/actions/guides/tutorial/03_design.cr
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ class Guides::Tutorial::Design < GuideAction

## Updating the Layout

As mentioned previously, we currently have two separate layouts. One for when users are logged in `MainLayout`, and one for
when users are logged out `AuthLayout`. These files live in the root of your `src/pages/` directory. We will update our `AuthLayout`
As mentioned previously, we currently have two separate layouts. One for when users are logged-in `MainLayout`, and one for
when users are logged-out `AuthLayout`. These files live in the root of your `src/pages/` directory. We will update our `AuthLayout`
to start so we can get a feel for writing HTML in Lucky.

When it comes to writing HTML in Lucky, we use plain Crystal methods that generate HTML for us!
[Read the HTML guide](#{Guides::Frontend::RenderingHtml.path}) for more details.
Read the [Rendering HTML guide](#{Guides::Frontend::RenderingHtml.path}) for more details.

### Anatomy of the layout

Expand All @@ -70,16 +70,16 @@ class Guides::Tutorial::Design < GuideAction

```crystal
# src/pages/auth_layout.cr
html class: "h-100", lang: "en" do
html lang: "en" do
mount Shared::LayoutHead, page_title: page_title

body class: "d-flex flex-column h-100" do
body do
mount Shared::FlashMessages, context.flash
main class: "flex-shrink-0" do
main class: "main-content" do
content
end

footer class: "footer mt-auto py-3 bg-light" do
footer class: "footer" do
div class: "container" do
span "CloverApp", class: "text-muted"
end
Expand All @@ -95,38 +95,25 @@ class Guides::Tutorial::Design < GuideAction

## Adding a CSS framework

If you haven't guessed by now, we've started adding [Bootstrap](https://getbootstrap.com/) classes to our HTML. You're free
to use any (or no) CSS framework you wish. There are no limitations since Lucky includes [LaravelMix](https://laravel-mix.com/)
which just wraps Webpack. We will stick with Bootstrap just for the purposes of this Tutorial.
You have the flexibility to use any (or no) css framework you would like. Lucky comes with [Bun](https://bun.sh/) out of the box
allowing you to add in packages as you need. For the purposes of this tutorial, we are going to keep it very simple and use
[SimpleCSS](https://simplecss.org/)

### Installing a CSS framework

Lucky uses `yarn` by default, so this tutorial will as well. If you prefer a different installation you may use that.

Before we install Bootstrap, we should shut down our server. (`ctrl-c`) Then from the terminal, we can run:
Before we install SimpleCSS, we should shut down our server. (`ctrl-c`) Then from the terminal, we can run:

```bash
yarn add bootstrap @popperjs/core
bun add simpledotcss
```

> PopperJS is required for some of the Bootstrap components such as dropdowns and popovers to function correctly.
Next we will import SimpleCSS in our stylesheet. Open up `src/css/app.css`. You'll find some default normalize styles in here.

Next we will import Bootstrap in our stylesheet. Open up `src/css/app.scss`. You'll find some default normalize styles in here. Now that we're using
a CSS framework, all of these can go away! Replace everything with this code:
Add this to the top:

```scss
// src/css/app.scss
@import "bootstrap";
```

Now, import Bootstrap into `src/js/app.js` to ensure the Bootstrap components that require Javascript function correctly.
Open that file and add this code:

```diff
// src/js/app.js
require("@rails/ujs").start();

+ import "bootstrap";
// src/css/app.css
@import "simpledotcss/simple.min.css";
```

Finally, restart the dev server from the terminal `lucky dev`.
Expand All @@ -144,13 +131,13 @@ class Guides::Tutorial::Design < GuideAction
```crystal
# src/pages/home/index_page.cr
def content
div class: "px-4 py-5 my-5 text-center" do
h1 "CloverApp", class: "display-5 fw-bold"
div class: "col-lg-6 mx-auto" do
para "It's your Lucky day! See a fortune, and share the luck.", class: "lead mb-4"
div class: "d-grid gap-2 d-sm-flex justify-content-sm-center" do
link "Join", to: SignUps::New, class: "btn btn-primary btn-lg px-4 me-sm-3"
link "Login", to: SignIns::New, class: "btn btn-outline-secondary btn-lg px-4"
div do
h1 "CloverApp", class: "title"
div do
para "It's your Lucky day! See a fortune, and share the luck.", class: "tagline"
div class: "button-group" do
link "Join", to: SignUps::New, class: "btn-primary"
link "Login", to: SignIns::New, class: "btn-secondary"
end
end
end
Expand All @@ -176,7 +163,7 @@ class Guides::Tutorial::Design < GuideAction
Try this:

* Add a copyright note to your footer that always displays the current year.
* Create a custom CSS style using normal raw CSS in your `src/css/app.scss`.
* Create custom CSS styles using normal raw CSS in your `src/css/app.css`.
* Apply that custom style to a tag on your Home Page.
* Update the styles for your Login / Signup pages

Expand Down
4 changes: 2 additions & 2 deletions src/actions/guides/tutorial/04_using_components.cr
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Guides::Tutorial::UsingComponents < GuideAction

```diff
# src/pages/auth_layout.cr
- footer class: "footer mt-auto py-3 bg-light" do
- footer class: "footer" do
- div class: "container" do
- span "CloverApp", class: "text-muted"
- end
Expand All @@ -50,7 +50,7 @@ class Guides::Tutorial::UsingComponents < GuideAction
```crystal
# src/components/shared/footer.cr
def render
footer class: "footer mt-auto py-3 bg-light" do
footer class: "footer" do
div class: "container" do
span "CloverApp", class: "text-muted"
end
Expand Down
2 changes: 1 addition & 1 deletion src/actions/guides/tutorial/05_operations_factories.cr
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Guides::Tutorial::OperationsFactories < GuideAction
```

You should now have a code editor open which may still show code from the last time we ran this.
Comment out any existing code and add this:
Comment out any code you previously added and add this below it:

```crystal
SignUpUser.create(email: "mytest@test.com", password: "notsecret", password_confirmation: "not_secret") do |operation, saved_user|
Expand Down
25 changes: 15 additions & 10 deletions src/actions/guides/tutorial/06_queries.cr
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,28 @@ class Guides::Tutorial::Queries < GuideAction
```crystal
# src/pages/home/index_page.cr
def content
div class: "px-4 py-5 my-5 text-center" do
# ... previous markup
div do
h1 "CloverApp", class: "title"
div do
para "It's your Lucky day! See a fortune, and share the luck.", class: "tagline"
div class: "button-group" do
link "Join", to: SignUps::New, class: "btn-primary"
link "Login", to: SignIns::New, class: "btn-secondary"
end
end
end
div class: "container" do
# Add this block of code here
div class: "list-group list-group-flush border-bottom scrollarea" do
fortunes.each do |fortune|
link to: Fortunes::Show.with(fortune.id), class: "list-group-item list-group-item-action py-3 lh-tight" do
div class: "d-flex w-100 align-items-center justify-content-between" do
# we're adding code here
fortunes.each do |fortune|
div class: "fortune-card" do
link to: Fortunes::Show.with(fortune.id) do
div class: "fortune-timestamp" do
small time_ago_in_words(fortune.created_at), class: "text-muted"
end
div fortune.text, class: "col-10 mb-1 small"
div fortune.text, class: "fortune-text"
end
end
end

end
end
```
Expand All @@ -131,7 +137,6 @@ class Guides::Tutorial::Queries < GuideAction
* Update your `UserFactory` to generate a random `name`.
* Update existing user records with a random name. (hint: search the guides (`ctrl-k`) for mention of "bulk updating")
* Update the fortunes to display the user's name that wrote it.

MD
end
end