### Run the Setup Script Source: https://luckyframework.org/guides/tutorial/overview Execute the `./script/setup` command to complete the application setup. This script checks dependencies, sets up assets, installs Crystal shards, creates the database, and runs migrations. ```bash ./script/setup ``` -------------------------------- ### Full System Check Example for Redis Source: https://luckyframework.org/guides/getting-started/starting-project This snippet demonstrates a comprehensive system check for Redis. It verifies if Redis is installed and running, providing specific instructions for starting it based on the operating system (macOS or Linux). ```bash if command_not_found "redis-cli"; then print_error "Redis is required, and must be installed" fi if command_not_running "redis-cli ping"; then if is_mac; booting_guide = "brew services start redis" fi if is_linux; booting_guide = "sudo systemctl start redis-server" fi print_error "Redis is not currently running. Try using " $booting_guide fi ``` -------------------------------- ### Install Nginx Source: https://luckyframework.org/guides/deploying/ubuntu Installs the Nginx web server on your Ubuntu system. ```bash sudo apt install nginx ``` -------------------------------- ### Generate a New Lucky Application Source: https://luckyframework.org/guides/tutorial/overview Use the `lucky init` command to start a new Lucky project. This command will guide you through naming your project and selecting the application type (API only or full support). ```bash lucky init ``` ```bash Project name?: clover ``` ```bash API only or full support for HTML and Webpack? (api/full): full ``` ```bash Generate authentication? (y/n): y ``` -------------------------------- ### Install PostgreSQL Source: https://luckyframework.org/guides/deploying/ubuntu Installs the PostgreSQL database server on Ubuntu. This is a prerequisite for creating and managing your application's database. ```bash sudo apt install postgresql ``` -------------------------------- ### Install Shards Source: https://luckyframework.org/guides/frontend/internationalization Install the project dependencies, including the newly added Rosetta shard. ```bash shards install ``` -------------------------------- ### Install Git Source: https://luckyframework.org/guides/deploying/ubuntu Installs the Git version control system. This is necessary for cloning your application's repository from a remote source. ```bash sudo apt install git ``` -------------------------------- ### Install Lucky CLI with Homebrew Source: https://luckyframework.org/guides/getting-started/installing Installs the Lucky CLI using the official Homebrew tap. This command should be run after installing necessary system dependencies. ```bash brew install luckyframework/homebrew-lucky/lucky ``` -------------------------------- ### Install Linux Dependencies (Ubuntu) Source: https://luckyframework.org/guides/getting-started/installing Installs essential development dependencies for Lucky on Ubuntu systems. ```bash apt-get install libc6-dev libevent-dev libpcre2-dev libpcre3-dev libpng-dev libssl-dev libyaml-dev zlib1g-dev ``` -------------------------------- ### Basic Pagination Series Example Source: https://luckyframework.org/guides/database/pagination Demonstrates the `series` method with default arguments, showing the resulting page numbers and gaps as integers and '..'. ```crystal # 10 pages of items and you are requesting page 5 series = pages.series(begin: 1, left_of_current: 1, right_of_current: 1, end: 1) series # [1, .., 4, 5, 6, .., 10] # All args default to 0 so you can leave them off. That means `begin|end` # are 0 in this example. series = pages.series(left_of_current: 1, right_of_current: 1) series # [4, 5, 6] # The current page is always shown series = pages.series(begin: 2, end: 2) series # [1, 2, .., 5, .., 9, 10] # The `series` method is smart and will not add gaps if there is no gap. # It will also not add items past the current page. series = pages.series(begin: 6) series # [1, 2, 3, 4, 5] ``` -------------------------------- ### Install Nexploit Repeater CLI Source: https://luckyframework.org/guides/testing/security-tests Install the Nexploit Repeater globally using npm. Ensure to use the `--unsafe-perm=true` flag if necessary. ```bash npm install -g @neuralegion/nexploit-cli --unsafe-perm=true ``` -------------------------------- ### Install Dependencies and Compile Assets Source: https://luckyframework.org/guides/deploying/ubuntu Installs project dependencies using Yarn and Shards, compiles production assets using Yarn, and then compiles the Lucky application in release mode. ```bash yarn install shards install yarn prod crystal build --release src/start_server.cr ``` -------------------------------- ### Start Lucky Development Server Source: https://luckyframework.org/guides/tutorial/overview Run this command in your terminal to start the Lucky development server. Use Ctrl-C to stop the server. ```bash lucky dev ``` -------------------------------- ### Start Lucky Application Source: https://luckyframework.org/guides/deploying/ubuntu Use this command to start your Lucky application after systemd has been reloaded. ```bash sudo service start ``` -------------------------------- ### Full Upsert Example Source: https://luckyframework.org/guides/database/saving-records Demonstrates creating a new user record and then updating it using the `upsert!` method based on a unique email address. ```crystal # Will create a new row in the database since no row with # `email: "bob@example.com"` exists yet SaveUser.upsert!(name: "Bobby", email: "bob@example.com") # Will update the name on the row we just created since the email is # the same as one in the database SaveUser.upsert!(name: "Bob", email: "bob@example.com") ``` -------------------------------- ### JSON API Example Source: https://luckyframework.org Defines an API endpoint to handle GET requests for a specific user and return user data in JSON format. It queries the database for the user and formats the response. ```crystal class Api::Users::Show < ApiAction get "/api/users/:user_id" do json user_json end private def user_json user = UserQuery.find(user_id) {name: user.name, email: user.email} end end ``` -------------------------------- ### Create Dokku App and Configure Database Source: https://luckyframework.org/guides/deploying/dokku Create a new application container, install the PostgreSQL plugin, create a database, link it to the app, and set initial environment variables for Lucky. ```bash dokku apps:create app.example.com # install the postgres plugin # plugin installation requires root, hence the user change sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git dokku postgres:create exampledb dokku postgres:link exampledb app.example.com dokku config:set app.example.com LUCKY_ENV=production dokku config:set app.example.com APP_DOMAIN=app.example.com dokku config:set app.example.com PORT=5000 ``` -------------------------------- ### Verify PostgreSQL CLI Client Installation Source: https://luckyframework.org/guides/getting-started/installing Checks if the PostgreSQL command-line client (psql) is installed and reports its version. ```bash psql --version ``` -------------------------------- ### Install Linux Dependencies (Fedora) Source: https://luckyframework.org/guides/getting-started/installing Installs essential development dependencies for Lucky on Fedora 28. ```bash dnf install glibc-devel libevent-devel pcre2-devel openssl-devel libyaml-devel zlib-devel libpng-devel ``` -------------------------------- ### Configure Habitat Setting Source: https://luckyframework.org/guides/getting-started/configuration Configure the settings defined by Habitat. This example sets the `api_token` for `MyStripeProcessor`. ```crystal MyStripeProcessor.configure do |settings| settings.api_token = "super secret" end ``` -------------------------------- ### Example Locale File Content Source: https://luckyframework.org/guides/frontend/internationalization This is an example of the `config/locales/example.en.yml` file content, providing translations for various parts of a Lucky application. ```yaml en: api: auth: not_authenticated: "Not authenticated." token_invalid: "The provided authentication token was incorrect." token_missing: | An authentication token is required. Please include a token in an 'auth_token' param or 'Authorization' header. default: button: sign_out: "Sign out" sign_up: "Sign up" error: incorrect_password: "is wrong" invalid_email: "is not in our system" field: email: "Email" language: "Language" password: "Password" password_confirmation: "Confirm password" errors: show_page: helpful_link: "Try heading back to home" page_title: "Something went wrong" me: show_page: after_signin: "Change where you go after sign in: src/actions/home/index.cr" auth_guides: "Check out the authentication guides" modify_page: "Modify this page: src/pages/me/show_page.cr" next_you_may_want_to: "Next, you may want to:" page_title: "This is your profile" user_email: "Email: %{email}" password_reset_requests: new_page: page_title: "Request password reset" password_resets: new_page: page_title: "Reset password" sign_ups: create: success: "Thanks for signing up" failure: "Couldn't sign you up" new_page: page_title: "Sign up" sign_in_instead: "Sign in instead" sign_ins: create: failure: "Sign in failed" success: "You're now signed in" delete: success: "You have been signed out" new_page: page_title: "Sign in" ``` -------------------------------- ### Materialized View Model Setup Source: https://luckyframework.org/guides/database/migrations Configure a model for a materialized view by skipping the schema enforcer and defining columns using the `view` macro. ```ruby class CampaignStat < BaseModel # The SchemaEnforcer must be ignored for materialzed views skip_schema_enforcer view do column campaign_id : UUID column amount : Int64 end # Use this to refresh your view periodically def self.refresh_view(*, concurrent : Bool = false) database.exec("REFRESH MATERIALIZED VIEW #{concurrent ? "CONCURRENTLY" : ""} #{table_name}") end end ``` -------------------------------- ### Check Crystal Installation Source: https://luckyframework.org/guides/getting-started/installing Verify that your Crystal installation is within the supported version range (>= 1.10.0, <= 1.16.3). ```bash crystal -v ``` -------------------------------- ### Basic Model Setup Source: https://luckyframework.org/guides/database/models A basic model structure inheriting from `BaseModel` with a `table` block for column definitions. ```crystal class User < BaseModel table do # You will define columns here. For example: # column name : String end end ``` -------------------------------- ### Install Lucky CLI with Scoop on Windows Source: https://luckyframework.org/guides/getting-started/installing Installs the Lucky CLI on Windows using the Scoop package manager. Note that Windows compatibility is experimental. ```bash scoop bucket add lucky https://github.com/luckyframework/scoop-bucket scoop install lucky ``` -------------------------------- ### Install Linux Dependencies (Debian) Source: https://luckyframework.org/guides/getting-started/installing Installs essential development dependencies for Lucky on Debian-based Linux systems. ```bash apt-get install libc6-dev libevent-dev libpcre2-dev libpng-dev libssl-dev libyaml-dev zlib1g-dev ``` -------------------------------- ### Define a GET route for Users Index Source: https://luckyframework.org/guides/http-and-routing/routing-and-params This snippet shows how to define a GET route for the Users Index action. The `get` macro specifies the HTTP method and the path. ```ruby # src/actions/users/index.cr class Users::Index < BrowserAction get "/users" do # `plain_text` sends plain/text to the client plain_text "Rendering something in Users::Index" end end ``` -------------------------------- ### Configure Shrine Storage Source: https://luckyframework.org/guides/handling-files/file-uploads Create a `config/shrine.cr` file to configure Shrine's storage. This example sets up file system storage for cache and uploads. ```crystal # config/shrine.cr Shrine.configure do |config| config.storages["cache"] = Shrine::Storage::FileSystem.new("public/uploads", prefix: "cache") config.storages["store"] = Shrine::Storage::FileSystem.new("public/uploads", prefix: "uploads") end ``` -------------------------------- ### Install Bootstrap and Popper.js Source: https://luckyframework.org/guides/tutorial/design Install the Bootstrap CSS framework and Popper.js, which is required for certain Bootstrap components. This command uses yarn, Lucky's default package manager. ```bash yarn add bootstrap @popperjs/core ``` -------------------------------- ### Nested HTML Structure Example Source: https://luckyframework.org/guides/frontend/rendering-html Shows how to create nested HTML structures, such as a list within the content method. ```crystal def content # You can have a list ul do li "List item" end # And underneath it render something else footer "Copyright Notice" end ``` -------------------------------- ### Check Lucky CLI Installation Source: https://luckyframework.org/guides/getting-started/installing Verifies that the Lucky CLI has been installed correctly and displays its version (expected: 1.4.1). ```bash lucky -v ``` -------------------------------- ### Dokku Procfile Configuration Source: https://luckyframework.org/guides/deploying/dokku Ensure the 'web' service in your Procfile is correctly configured to run the Lucky application executable. The example shows './app'. ```text web: ./app # ... ``` -------------------------------- ### Check Node and Yarn Versions Source: https://luckyframework.org/guides/getting-started/installing Verifies that Node.js is installed and meets the minimum version requirement (v11), and checks the installed Yarn version. ```bash node -v yarn -v ``` -------------------------------- ### Install OpenSSL on macOS Source: https://luckyframework.org/guides/getting-started/installing Installs OpenSSL using Homebrew, a dependency required for Crystal on macOS. ```bash brew install openssl ``` -------------------------------- ### Database Model and Query Setup Source: https://luckyframework.org Sets up a User model with a database table definition and adds query methods for filtering and sorting users. This snippet demonstrates how to define models and create custom query objects. ```crystal # Set up the model class User < BaseModel table do column last_active_at : Time column last_name : String end end # Add some methods to help query the database class UserQuery < User::BaseQuery def recently_active last_active_at.gt(1.week.ago) end def sorted_by_last_name last_name.lower.desc_order end end # Query the database UserQuery.new.recently_active.sorted_by_last_name ``` -------------------------------- ### Create a Simple Form with Operations Source: https://luckyframework.org/guides/frontend/html-forms This example demonstrates building a form for saving or updating a post using `form_for`, `label_for`, `text_input`, `textarea`, and `submit`. It also shows how to integrate `error_for` to display validation messages. ```ruby # src/operations/save_post.cr class SavePost < Post::SaveOperation permit_columns title, body end # src/pages/posts/edit_page.cr class Posts::EditPage < MainLayout needs op : SavePost def content form_for(Posts::Update) do para do label_for(op.title) text_input(op.title) error_for(op.title) end para do label_for(op.body) textarea(op.body) error_for(op.body) end submit("Update Post", class: "btn") end end private def error_for(field) mount Shared::FieldErrors, field end end ``` -------------------------------- ### Install Lucky CLI Shards Source: https://luckyframework.org/guides/getting-started/installing Installs the necessary Crystal 'shards' (packages/libraries) for the Lucky CLI, excluding development dependencies. ```bash shards install --without-development ``` -------------------------------- ### Define a route with optional path parameters Source: https://luckyframework.org/guides/http-and-routing/routing-and-params This example shows how to define routes with optional path parameters using the `?` prefix. This allows for more flexible URL structures, handling cases where a parameter might be present or absent. ```ruby # src/actions/posts/index.cr class Posts::Index < BrowserAction get "/posts/:year/:month/?:day" do if day plain_text "I'll show all posts on a specific day!" else plain_text "I'll show all posts in a given month!" end end end ``` -------------------------------- ### Getting Help for a Specific Task Source: https://luckyframework.org/guides/command-line-tasks/built-in To get detailed information about a specific task, use the '-h' or '--help' flag followed by the task name. ```bash lucky db.migrate --help ``` -------------------------------- ### Example ECR Template for a Blog Post Form Source: https://luckyframework.org/guides/frontend/rendering-html An example of an ECR template file (`src/posts/new.html.ecr`) that renders a blog post form. It uses the `@operation` instance variable passed from the page. ```ecr

New Blog Post

<% render_post_form(@operation) %> ``` -------------------------------- ### Glob Routing Example Source: https://luckyframework.org/guides/http-and-routing/routing-and-params Use a `*` at the end of a route path to capture an unknown number of path segments. The captured path is available via the `glob` method. ```crystal class Posts::Index < BrowserAction get "/posts/*" do if glob # glob == "2022/02/14" else # the path was just "/posts" end end end ``` -------------------------------- ### Page Inheriting from MainLayout Source: https://luckyframework.org/guides/authentication/browser An example of a page that inherits from MainLayout, used in conjunction with a browser action that allows guests. ```ruby class Posts::IndexPage < MainLayout needs posts : PostQuery def content # html the page contents end end ``` -------------------------------- ### Define DATABASE_URL Connection String Source: https://luckyframework.org/guides/database/database-setup Example of setting the DATABASE_URL environment variable for PostgreSQL connections, including options for standard credentials or local unix sockets. ```shell # Define your connection string DATABASE_URL=postgres://myuser:somepass@localhost:5432/my_db?retry_attempts=2 ``` ```shell # Or use a local unix socket DATABASE_URL=postgres:///my_db ``` -------------------------------- ### Sign Up User with API Source: https://luckyframework.org/guides/authentication/api Use the `Api::SignUps::Create` action to register a new user. It requires email, password, and password confirmation, returning an authentication token upon success. ```bash curl localhost:5000/api/sign_ups -X POST -d "user:email=person@example.com" -d "user:password=password" -d "user:password_confirmation=password" ``` -------------------------------- ### Install Homebrew on macOS Source: https://luckyframework.org/guides/getting-started/installing Installs Homebrew, a package manager for macOS, which is a prerequisite for installing Lucky CLI on macOS. ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` -------------------------------- ### Rendering HTML with Data Source: https://luckyframework.org Handles a GET request for the /users route, fetches sorted users from the database, and renders an HTML page. It demonstrates how to associate routes with specific page components and pass data to them. ```crystal class Users::Index < BrowserAction get "/users" do users = UserQuery.new.sorted_by_last_name html IndexPage, users: users end end class Users::IndexPage < MainLayout needs users : UserQuery def content ul class: "users-list" do users.each do |user| li { link user.name, to: Users::Show.with(user) } end end end end ``` -------------------------------- ### Route Prefixing Example Source: https://luckyframework.org/guides/http-and-routing/routing-and-params The `route_prefix` macro groups routes under a common path, such as API versioning. Actions inheriting from a base action with a prefix will automatically include it. ```crystal abstract class ApiAction < Lucky::Action accepted_formats [:json], default: :json route_prefix "/api/v1" end ``` ```crystal class Api::Posts::Index < ApiAction # GET /api/v1/posts get "/posts" do json(PostQuery.new) end end ``` ```crystal class Posts::Index < BrowserAction # This is NOT prefixed because it inherits from # BrowserAction. # GET /posts get "/posts" do html IndexPage end end ``` -------------------------------- ### Fallback Routing Example Source: https://luckyframework.org/guides/http-and-routing/routing-and-params Use the `fallback` macro to implement a catch-all behavior, useful for SPAs. It should include a `Lucky::RouteNotFoundError` to handle 404s for missing assets. ```crystal class Frontend::Index < BrowserAction fallback do if html? html Home::IndexPage else raise Lucky::RouteNotFoundError.new(context) end end end ``` -------------------------------- ### Create Application Directory Source: https://luckyframework.org/guides/deploying/ubuntu Creates a directory at /srv/ to store the application's code and assigns ownership to the 'deploy' user. ```bash sudo mkdir /srv/ sudo chown deploy:deploy /srv/ ``` -------------------------------- ### Customize the Root Page Redirect Source: https://luckyframework.org/guides/http-and-routing/routing-and-params This example shows how to customize the default root path ('/'). It demonstrates redirecting users based on their login status, either to a personalized page or a sign-in page. ```ruby # src/actions/home/index.cr class Home::Index < BrowserAction include Auth::AllowGuests get "/" do if current_user? redirect Me::Show else # When you're ready change this line to: # # redirect SignIns::New # # Or maybe show signed out users a marketing page: # # html Marketing::IndexPage html Lucky::WelcomePage end end end ``` -------------------------------- ### Configure Habitat Setting with ENV Variable Source: https://luckyframework.org/guides/getting-started/configuration Configure Habitat settings using environment variables for better security and flexibility. This example fetches the API token from `STRIPE_API_TOKEN`. ```crystal MyStripeProcessor.configure do |settings| settings.api_token = ENV.fetch("STRIPE_API_TOKEN") end ``` -------------------------------- ### Initialize Custom Lucky App with Security Tests Source: https://luckyframework.org/guides/testing/security-tests Use the `init.custom` command with the `--with-sec-test` flag to generate a new Lucky application pre-configured for security testing. ```bash lucky init.custom my_app --with-sec-test ``` -------------------------------- ### Example JSON Object Source: https://luckyframework.org/guides/json-and-apis/parsing-json-requests This is the structure of the JSON object used in the examples for parsing requests. ```json { "pay_date": "2021-02-15 10:00:00", "issue_date": "2021-01-31 14:00:00", "lines": [ {"text": "Item One", "unit": "USD", "amount": 5500, "tax": 3.8}, {"text": "Item Two", "unit": "USD", "amount": 1032, "tax": 3.8}, ] } ``` -------------------------------- ### Create and Validate User with SaveOperation Source: https://luckyframework.org/guides/tutorial/operations-and-factories Demonstrates how to instantiate and execute a `SignUpUser` SaveOperation with specific parameters. It shows how to check for errors and inspect the saved user object. ```crystal SignUpUser.create(email: "mytest@test.com", password: "notsecret", password_confirmation: "not_secret") do |operation, saved_user| pp operation.errors pp saved_user end ``` -------------------------------- ### Basic CORS Handler Setup Source: https://luckyframework.org/guides/json-and-apis/cors Implement a basic CORS handler by adding necessary headers to allow cross-origin requests. This handler should be placed in your application's middleware stack. ```crystal class CORSHandler include HTTP::Handler def call(context) context.response.headers["Access-Control-Allow-Origin"] = "*" context.response.headers["Access-Control-Allow-Headers"] = "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" context.response.headers["Access-Control-Allow-Methods"] = "*" call_next(context) end end ``` -------------------------------- ### Navigate to Project Directory Source: https://luckyframework.org/guides/tutorial/overview After generating the application, change your current directory to the newly created project folder. ```bash cd clover ``` -------------------------------- ### Define Configuration Setting with Habitat Source: https://luckyframework.org/guides/getting-started/configuration Use Habitat to define type-safe configuration settings within your application classes. This example shows how to define an API token setting. ```crystal class MyStripeProcessor Habitat.create do setting api_token : String end end ``` -------------------------------- ### Generating Links with Raw Path and Query Parameters Source: https://luckyframework.org/guides/http-and-routing/link-generation Illustrates how to use the `path` method directly to construct a URL with arbitrary query parameters, using the `a` HTML helper for direct link creation. ```crystal def content a "Search again", href: Search::Index.path + "?a=1&b=2" end ``` -------------------------------- ### Setting and Getting Cookies and Session Values Source: https://luckyframework.org/guides/http-and-routing/sessions-and-cookies Demonstrates how to set and retrieve string and symbol-keyed values from cookies and the session in a Lucky browser action. Note that session keys are expected to be Symbols. ```crystal class FooAction < BrowserAction get "/foo" do cookies.set("name", "Sally") cookies["name"] = "Sally" cookies.get("name") # Will return "Sally" cookies["name"] # or use shorthand cookies.get?("person") # Will return nil cookies["person"]? # You can use Symbol for your key as well session.set(:name, "Sally") session.get(:name) # Will return "Sally" session.get("person") # oops! An exception is raised because this key doesn't exist plain_text "Cookies!" end end ``` -------------------------------- ### Displaying Extended Task Help Message Source: https://luckyframework.org/guides/command-line-tasks/custom-tasks After defining a custom `help_message`, using the -h flag will now display the extended help information, including optional environment variables and examples. ```bash $ lucky generate_sitemaps -h Generate the sitemap.xml for this site Optionally, you can pass the 'DOMAIN' env to specify which domain to generate a sitemap on. example: lucky generate_sitemap DOMAIN=company.xyz ``` -------------------------------- ### Push Application Code to Heroku Source: https://luckyframework.org/guides/deploying/heroku Uploads your local application code to Heroku. Heroku will detect the Node.js and Crystal components, download dependencies, compile the code, and start the application. Database migrations are handled automatically during this process. ```bash git push heroku main ``` -------------------------------- ### Initialize Rosetta for Lucky Source: https://luckyframework.org/guides/frontend/internationalization Run the Rosetta init command with the `--lucky` flag to set up required files and Lucky integration. ```bash bin/rosetta --init --lucky ``` -------------------------------- ### Get Asset Path Outside of Pages Source: https://luckyframework.org/guides/frontend/asset-handling The `Lucky::AssetHelpers.asset` method can be used to get asset paths from anywhere within your Lucky application, not just pages or components. ```ruby Lucky::AssetHelpers.asset("images/logo.png") ``` -------------------------------- ### Enable Nginx Site Configuration Source: https://luckyframework.org/guides/deploying/ubuntu Create a symbolic link to enable your Nginx configuration file for your Lucky application. ```bash sudo ln -s /etc/nginx/sites-available/.conf /etc/nginx/sites-enabled/.conf ``` -------------------------------- ### Get Asset Path in Lucky Pages Source: https://luckyframework.org/guides/frontend/asset-handling Use the `asset` helper in Lucky pages or components to get the fingerprinted path to assets located in the `public/assets` folder. ```html img src: asset("images/logo.png") ``` -------------------------------- ### Find rows where A like B (starts with) Source: https://luckyframework.org/guides/database/querying-records Use the `like` method for case-sensitive pattern matching, typically used for checking if a string starts with a specific prefix. ```crystal UserQuery.new.name.like("John%") ``` -------------------------------- ### Configure Dokku Let's Encrypt SSL Source: https://luckyframework.org/guides/deploying/dokku Set up a Let's Encrypt SSL certificate for your Dokku application. Provide your email address for certificate notifications and then run the Let's Encrypt command. ```bash dokku config:set --no-restart app.example.com DOKKU_LETSENCRYPT_EMAIL=your.email@example.com dokku letsencrypt app.example.com ``` -------------------------------- ### Sign In User and Generate Auth Token Source: https://luckyframework.org/guides/authentication/api Use the `Api::SignIns::Create` action to authenticate an existing user. It requires email and password, returning an authentication token upon successful login. ```bash curl localhost:5000/api/sign_ins -X POST -d "user:email=person@example.com" -d "user:password=password" ``` -------------------------------- ### Configuring Session Store Source: https://luckyframework.org/guides/getting-started/why-lucky Demonstrates how to configure the session store and highlights the compile-time error that occurs if a required setting like 'secret' is not provided. ```crystal LuckyWeb::Session::Store.configure do |settings| settings.key = "my_app" end ``` ```crystal LuckyWeb::Session::Store.settings.secret was nil, but the setting is required. Please set it. Example: LuckyWeb::Session::Store.configure do |settings| settings.secret = "some_value" end ``` -------------------------------- ### Dokku CHECKS File Source: https://luckyframework.org/guides/deploying/dokku Create a CHECKS file at the root of your project to speed up post-deploy checks on Dokku. Sets a wait time of 5 seconds. ```text WAIT=5 ``` -------------------------------- ### Foreign Key Constraint Example Source: https://luckyframework.org/guides/database/migrations Illustrates the generated SQL for a foreign key constraint with `ON DELETE CASCADE`. ```sql comments_author_id_fkey" FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE ``` -------------------------------- ### Generate a New Lucky Project with Custom Options Source: https://luckyframework.org/guides/getting-started/starting-project Use `lucky init.custom` to create a new Lucky project programmatically or with specific flags. This allows for quick customization without the interactive wizard. ```bash # Generate a Full Web app with Authentication lucky init.custom my_app # Generate an API only app lucky init.custom my_app --api # Skip generating User Auth lucky init.custom my_app --no-auth # Customize the directory where your app is generated. # Default is your current directory lucky init.custom my_app --dir /home/me/projects # Generate your application with security specs from BrightSec lucky init.custom my_app --with-sec-test ``` -------------------------------- ### Creating a Record with Factory.create Source: https://luckyframework.org/guides/testing/creating-test-data This snippet shows the basic usage of `Factory.create` to instantiate and save a record to the database using the factory's default values. ```crystal post = PostFactory.create post.title #=> "post-title-1" post2 = PostFactory.create post2.title #=> "post-title-2" ``` -------------------------------- ### Add lucky_cache Dependency Source: https://luckyframework.org/guides/frontend/rendering-html Include `lucky_cache` in your `shards.yml` file to add it as a project dependency. Run `shards install` afterwards. ```yaml dependencies: lucky_cache: github: luckyframework/lucky_cache ``` -------------------------------- ### Run Migrations with Environment Variables Source: https://luckyframework.org/guides/deploying/ubuntu Runs database migrations while specifying necessary environment variables, including the DATABASE_URL, which is required for the migration process to connect to the database. ```bash API_KEY= SUPPORT_EMAIL= DATABASE_URL=postgres://:@127.0.0.1/_production crystal run tasks.cr -- db.migrate ``` -------------------------------- ### Check Element Visibility Source: https://luckyframework.org/guides/testing/html-and-interactivity Verify if an element is currently displayed on the page. This example demonstrates checking visibility before and after a hover action. ```html
Drop Files Here
Ready for upload!
``` ```ruby el(".alert-box").displayed? #=> false el("@file-upload-box").hover el(".alert-box").displayed? #=> true ``` -------------------------------- ### Define User Model Source: https://luckyframework.org/guides/database/querying-records Example of a User model definition with name, age, and admin columns, and a has_many association to tasks. ```crystal class User < BaseModel table :users do # `id`, `created_at`, and `updated_at` are predefined for us column name : String column age : Int32 column admin : Bool has_many tasks : Task end end ``` -------------------------------- ### Select Input with Prompt Source: https://luckyframework.org/guides/frontend/html-forms Generates an HTML select dropdown that includes a prompt option. This is useful for guiding user selection. ```elixir select_input(op.car_make, class: "custom-select") do select_prompt("Select your car") options_for_select(op.car_make, [{"Honda", 1}, {"Toyota", 2}]) end ``` ```html ``` -------------------------------- ### Clone Lucky CLI Repository Source: https://luckyframework.org/guides/getting-started/installing Clones the Lucky CLI source code repository from GitHub to your local machine for manual installation. ```bash git clone https://github.com/luckyframework/lucky_cli ``` -------------------------------- ### Add Lucky Framework Buildpack Source: https://luckyframework.org/guides/deploying/heroku Add the Lucky framework's buildpack to Heroku to enable the compilation and installation of Lucky dependencies. ```bash heroku buildpacks:add lucky-framework/lucky ``` -------------------------------- ### Defining a Route for a Browser Action Source: https://luckyframework.org/guides/http-and-routing/link-generation Defines a `BrowserAction` with a GET route that matches a specific URL pattern, including a dynamic parameter. ```crystal class Projects::Users::Index < BrowserAction get "/projects/:project_id/users" do plain_text "Users" end end ``` -------------------------------- ### Create PostgreSQL Database Source: https://luckyframework.org/guides/deploying/ubuntu Creates a new PostgreSQL database named '_production' and assigns ownership to the 'deploy' user. This is done by first switching to the 'postgres' user. ```bash sudo su - postgres createdb -O deploy _production ``` -------------------------------- ### Rendering Form for User Creation Source: https://luckyframework.org/guides/database/saving-records Shows how to render an HTML form for creating a new user using Avram's form helpers. It highlights the need to permit columns for form submission. ```crystal # src/pages/users/new_page.cr class Users::NewPage < MainLayout needs save_user : SaveUser def content render_form(save_user) end private def render_form(operation) form_for Users::Create do label_for operation.name text_input operation.name submit "Save User" end end end ``` -------------------------------- ### Named Glob Routing Example Source: https://luckyframework.org/guides/http-and-routing/routing-and-params Glob routes can be named by assigning the `*` to a path parameter. The captured path will then be available through that named parameter. ```crystal class Posts::Index < BrowserAction get "/posts/*:date" do if date # date == "2022/02/14" else # the path was just "/posts" end end end ``` -------------------------------- ### Email HTML Template Source: https://luckyframework.org/guides/emails/sending-emails-with-carbon Example of an HTML email template using ECR for interpolation. Instance variables from the email class are available. ```html

Welcome, <%= @user.name %>!

...

Secret token <%= @token %>.

Thanks, <%= email_signature %>

``` -------------------------------- ### Create a Heroku App Source: https://luckyframework.org/guides/deploying/heroku Use this command to create a new application on Heroku if one does not already exist. ```bash heroku create ``` -------------------------------- ### Skip Schema Enforcer for a Model Source: https://luckyframework.org/guides/database/models Add `skip_schema_enforcer` to a model to bypass schema enforcement. This is useful for custom setups or temporary models. ```ruby class TempOTPUser < Avram::Model skip_default_columns # Add this line to skip checking this model skip_schema_enforcer def self.database : Avram::Database.class AppDatabase end table :users do primary_key id : UUID # or whatever your PKEY type is... column otp_code : String? end end ``` -------------------------------- ### Implement Optional Help Section in Page Source: https://luckyframework.org/guides/frontend/rendering-html Provides an optional `help_section` method in a page to render specific help content within the layout. ```ruby # If a page has a help section, add a `help_section` method class Admin::Users::IndexPage < MainLayout def help_section para "Click the 'export' button to export a CSV of all users" end end ``` -------------------------------- ### Installing Kilt Templating Engine Source: https://luckyframework.org/guides/frontend/rendering-html Shows how to add the Kilt gem to your project's dependencies. Kilt is a templating engine that can be integrated with Lucky. ```yaml dependencies: kilt: github: jeromegn/kilt ``` -------------------------------- ### Generate SQL and Arguments Source: https://luckyframework.org/guides/database/querying-records Use `to_sql` to get the generated SQL query and its corresponding arguments as an array. This is useful for manual verification during development. ```crystal UserQuery.new .name("Stan") .age(45) .limit(1) .to_sql #=> ["SELECT COLUMNS FROM users WHERE users.name = $1 AND users.age = $2 LIMIT $3", "Stan", 45, 1] ``` -------------------------------- ### Setting and Getting Raw Unencrypted Cookies Source: https://luckyframework.org/guides/http-and-routing/sessions-and-cookies Shows how to set and retrieve raw, unencrypted cookie values using `set_raw` and `get_raw` methods. ```crystal cookies.set_raw("name", "Sally") # Sets a raw unencrypted cookie cookies.get_raw("name") # Will return "Sally" cookies.get_raw?("person") # Will return nil ``` -------------------------------- ### Add Dokku Git Remote and Deploy Source: https://luckyframework.org/guides/deploying/dokku Add your Dokku server as a Git remote and push your local main branch to deploy the Lucky application. Replace 'ip' and 'app.example.com' accordingly. ```bash git remote add dokku dokku@ip:app.example.com git push dokku main ``` -------------------------------- ### Check if User is Signed In Source: https://luckyframework.org/guides/authentication Use `current_user` within actions to get the signed-in user. If sign-in is optional, check if the user is nil before proceeding. ```crystal class Hello::Show < BrowserAction include Auth::AllowGuests get "/hello" do user = current_user if user plain_text "Hello #{user.name}" else plain_text "Hello!" end end end ``` -------------------------------- ### Run Database Migrations Source: https://luckyframework.org/guides/frontend/internationalization Executes all pending database migrations. ```bash lucky db.migrate ``` -------------------------------- ### Execute Raw SQL in Migrations Source: https://luckyframework.org/guides/database/migrations Demonstrates how to execute raw SQL statements directly within a migration using the `execute` method. This is useful for complex SQL or features not yet supported by the framework. ```ruby def migrate execute <<-SQL CREATE TABLE admins ( id character varying(18) NOT NULL, email character varying NOT NULL, password_digest character varying NOT NULL, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL ); SQL end ``` -------------------------------- ### Define a Welcome Email Class Source: https://luckyframework.org/guides/emails/sending-emails-with-carbon Defines a basic email class with an initializer that sets up an encryption token. ```crystal class WelcomeEmail < BaseEmail # Define your own initializer with the # references it needs def initializer(@user : User) encryptor = Lucky::MessageEncryptor.new(secret: Lucky::Server.settings.secret_key_base) # Instance variables defined are available in your templates @token = encryptor.encrypt_and_sign("#{@user.id}:#{24.hours.from_now.to_unix_ms}") end to @user subject "Welcome to MyApp.io!" templates html, text end ``` -------------------------------- ### Get Dynamic Asset Path in Lucky Pages Source: https://luckyframework.org/guides/frontend/asset-handling Use the `dynamic_asset` helper when the asset path is only known at runtime. This is useful for dynamically generated filenames. ```html img src: dynamic_asset("images/#{name}.png") ``` -------------------------------- ### Configure Avram Database Credentials Source: https://luckyframework.org/guides/database/database-setup Set up database connection credentials using Avram::Credentials.new with standard options like database name, hostname, port, username, and password. Includes connection pool settings via the query string. ```crystal AppDatabase.configure do |settings| settings.credentials = Avram::Credentials.new( database: database_name, hostname: "localhost", port: 5432, username: "lucky", password: "lucky", query: "initial_pool_size=5&retry_attempts=2" ) end ``` -------------------------------- ### Configure SVG Inliner Path Source: https://luckyframework.org/guides/frontend/rendering-html Customize the directory where Lucky looks for SVG files by defining an annotation in an initializer. This example sets the path to `src/icons`. ```ruby # config/svg_inliner.cr @[Lucky::SvgInliner::Path("src/icons")] module Lucky::SvgInliner end ``` -------------------------------- ### Create Simple SQL Function Source: https://luckyframework.org/guides/database/migrations Creates a basic SQL function in the database. This example defines a trigger function that automatically updates a timestamp column. ```crystal def migrate # simple trigger function create_function "set_updated_at", <<-SQL IF NEW.updated_at IS NULL OR NEW.updated_at = OLD.updated_at THEN NEW.updated_at := now(); END IF; RETURN NEW; SQL end ``` -------------------------------- ### Add PostgreSQL Database Add-on Source: https://luckyframework.org/guides/deploying/heroku Create a 'hobby-dev' tier PostgreSQL database add-on for the Heroku application. ```bash heroku addons:create heroku-postgresql:hobby-dev ``` -------------------------------- ### Serving a File for Download Source: https://luckyframework.org/guides/http-and-routing/request-and-response The `file` method serves a file to the browser, allowing you to specify disposition (attachment/inline), filename, and content type. ```crystal class Reports::Show < BrowserAction get "/reports/sales" do file "/path/to/reports.pdf", disposition: "attachment", filename: "report-#{Time.utc.month}.pdf", content_type: "application/pdf" end end ``` -------------------------------- ### Browser Action Allowing Guests Source: https://luckyframework.org/guides/authentication/browser An example of a browser action that inherits from BrowserAction and includes Auth::AllowGuests, making it accessible to both signed-in users and guests. ```ruby class Posts::Index < BrowserAction include Auth::AllowGuests get "/posts" do html Posts::IndexPage, posts: PostQuery.new end end ``` -------------------------------- ### Add Shrine Shard to Lucky Project Source: https://luckyframework.org/guides/handling-files/file-uploads Add the shrine shard to your `shard.yml` to enable file upload functionality. Run `shards install` after updating the file. ```yaml dependencies: shrine: github: jetrockets/shrine.cr branch: master ``` -------------------------------- ### Configuring Force SSL and HSTS Source: https://luckyframework.org/guides/http-and-routing/security-headers Enable `Lucky::ForceSSLHandler` and configure Strict-Transport-Security settings in `config/server.cr`. ```crystal # config/server.cr Lucky::ForceSSLHandler.configure do |settings| settings.enabled = LuckyEnv.production? settings.strict_transport_security = {max_age: 1.year, include_subdomains: true} end ``` -------------------------------- ### Accessing Query String Parameters Source: https://luckyframework.org/guides/http-and-routing/routing-and-params Access query string parameters directly using the `params` method. This example shows accessing 'page' and 'filter' parameters. ```crystal # Example usage with params method # when visiting the /users?page=1&filter=active path ``` -------------------------------- ### Define a route for OPTIONS method Source: https://luckyframework.org/guides/http-and-routing/routing-and-params This snippet demonstrates how to handle less common HTTP methods like OPTIONS using the `match` macro. This is useful for specific API interactions. ```ruby # src/actions/profile/show.cr class Profile::Show < BrowserAction # Respond to an `HTTP OPTIONS` request match :options, "/profile" do # action code here end end ``` -------------------------------- ### Create Sample Seed Data Source: https://luckyframework.org/guides/database/database-setup Use this task to populate your development database with fake data for testing purposes. This code goes into `tasks/db/seed/sample_data.cr`. ```crystal def call # Using a Factory 100.times do ProductFactory.create end # Using an Operation 100.times do |i| SaveProduct.create!(name: "Product #{i}") end end ``` -------------------------------- ### Add Heroku Buildpacks Source: https://luckyframework.org/guides/deploying/heroku Add the Node.js buildpack first for assets, followed by the Lucky framework buildpack for Crystal compilation. ```bash # Skip this buildpack for API only app. Add this for HTML and Assets heroku buildpacks:add heroku/nodejs # Then add this for all Lucky apps heroku buildpacks:add lucky-framework/lucky ``` -------------------------------- ### Creating a Custom Target with SecTester::Target Source: https://luckyframework.org/guides/testing/security-tests When a custom target is needed, you can use `SecTester::Target` directly. This example constructs a target pointing to a JavaScript asset. ```ruby target = SecTester::Target.new(Lucky::RouteHelper.settings.base_uri + Lucky::AssetHelpers.asset("js/app.js")) ``` -------------------------------- ### Push to Heroku Source: https://luckyframework.org/guides/deploying/heroku Deploy the application to Heroku by pushing the main branch to the Heroku remote. ```bash git push heroku main ``` -------------------------------- ### Persisting Flash Messages Through Redirect Source: https://luckyframework.org/guides/http-and-routing/flash To ensure flash messages are displayed after a `redirect`, use `flash.keep` before setting the message. This example demonstrates a message that will show after a redirect. ```crystal class Home::Index < BrowserAction get "/" do if current_user flash.keep flash.success = "Now I will show, because of flash.keep!" redirect to: Me::Show else flash.success = "I will show, because we're rendering without calling a new action!" html Home::IndexPage end end end ``` -------------------------------- ### Flash Message Behavior with Redirect (Default) Source: https://luckyframework.org/guides/http-and-routing/flash By default, flash messages are cleared when a `redirect` is called. This example shows a message that won't display after a redirect. ```crystal class Home::Index < BrowserAction get "/" do if current_user flash.failure = "I won't show, because we're using a redirect!" redirect to: Me::Show else flash.success = "I will show, because we're rendering a page!" html Home::IndexPage end end end ```