- Upgrade to crystal 0.31.1
- Upgrade Lucky CLI (homebrew)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date. Requires 0.31.1
brew upgrade lucky
-
Upgrade Lucky CLI (Linux)
-
Update
.crystal-version
to0.31.1
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/getting-started/installing#on-linux
- Update versions in
shard.yml
- Crystal should be
0.31.1
- Lucky should be
~> 0.18
- Authentic should be
~> 0.5.0
- LuckyFlow should be
~> 0.6.0
- Crystal should be
- Run
shards update
-
Rename: all
render
calls in actions tohtml
. -
Update: the
src/actions/errors/show.cr
file to the new format:class Errors::Show < Lucky::ErrorAction DEFAULT_MESSAGE = "Something went wrong." default_format :html dont_report [Lucky::RouteNotFoundError] def render(error : Lucky::RouteNotFoundError) if html? error_html "Sorry, we couldn't find that page.", status: 404 else error_json "Not found", status: 404 end end # When the request is JSON and an InvalidOperationError is raised, show a # helpful error with the param that is invalid, and what was wrong with it. def render(error : Avram::InvalidOperationError) if html? error_html DEFAULT_MESSAGE, status: 500 else error_json \ message: error.renderable_message, details: error.renderable_details, param: error.invalid_attribute_name, status: 400 end end # Always keep this below other 'render' methods or it may override your # custom 'render' methods. def render(error : Lucky::RenderableError) if html? error_html DEFAULT_MESSAGE, status: error.renderable_status else error_json error.renderable_message, status: error.renderable_status end end # If none of the 'render' methods return a response for the raised Exception, # Lucky will use this method. def default_render(error : Exception) : Lucky::Response if html? error_html DEFAULT_MESSAGE, status: 500 else error_json DEFAULT_MESSAGE, status: 500 end end private def error_html(message : String, status : Int) context.response.status_code = status html Errors::ShowPage, message: message, status: status end private def error_json(message : String, status : Int, details = nil, param = nil) json ErrorSerializer.new(message: message, details: details, param: param), status: status end private def report(error : Exception) : Nil # Send to Rollbar, send an email, etc. end end
-
Rename:
title
tomessage
insrc/pages/errors/show_page.cr
. -
Add:
BaseSerializer
tosrc/serializers/
.abstract class BaseSerializer < Lucky::Serializer def self.for_collection(collection : Enumerable, *args, **named_args) collection.map do |object| new(object, *args, **named_args) end end end
-
Add:
require "./serializers/base_serializer"
to yoursrc/app.cr
aboverequire "./serializers/**"
-
Optional: Update all serializers to inherit from
BaseSerializer
. Also merge Show/Index serializers in to a single class.# Merge these two classes class Users::IndexSerializer < Lucky::Serializer end class Users::ShowSerializers < Lucky::Serializer end # in to this class class UserSerializer < BaseSerializer # Same contents as Users::ShowSerializer # Calls to Users::IndexSerializer now become: # # UserSerializer.for_collection(users) end
-
Rename:
Errors::ShowSerializer
toErrorSerializer
-
Update:
ErrorSerializer
to inherit from the newBaseSerializer
-
Update:
ErrorSerializer
contents with:class ErrorSerializer < BaseSerializer def initialize( @message : String, @details : String? = nil, @param : String? = nil # If there was a problem with a specific param ) end def render {message: @message, param: @param, details: @details} end end
-
Add:
Avram::SchemaEnforcer.ensure_correct_column_mappings!
tosrc/start_server.cr
belowAvram::Migrator::Runner.new.ensure_migrated!
. -
Update: any mention to renamed errors in this commit. You can likely ignore this as most people do not rescue these specific errors.
-
Add:
accepted_formats [:json]
toApiAction
insrc/actions/api_action.cr
.abstract class ApiAction < Lucky::Action accepted_formats [:json] end
-
Add:
accepted_formats [:html, :json], default: :html
toBrowserAction
insrc/actions/browser_action.cr
abstract class BrowserAction < Lucky::Action accepted_formats [:html, :json], default: :html end
-
Update:
src/app_server.cr
with explicit return type on themiddleware
method.
# Add return type here
def middleware : Array(HTTP::Handler)
[
# ...
] of HTTP::Handler # Add this or app will fail to compile
end
- Add:
include Lucky::RequestExpectations
tospec/spec_helper.cr
belowinclude Carbon::Expectations
- Add:
Avram::SchemaEnforcer.ensure_correct_column_mappings!
tospec/spec_helper.cr
belowAvram::Migrator::Runner.new.ensure_migrated!
- Update: Change
at_exit do
inspec/setup/start_app_server.cr
toSpec.after_suite do
- Ensure you've upgraded to crystal 0.30.1
- Upgrade Lucky CLI (homebrew)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date. Requires 0.30.1
brew upgrade lucky
-
Upgrade Lucky CLI (Linux)
-
Update
.crystal-version
to0.30.1
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/getting-started/installing#on-linux
- Update versions in
shard.yml
- Lucky should be
~> 0.17
- Lucky should be
- Run
shards update
If you're not sure about an upgrade step, or simply want to look at an example, see the lucky_bits upgrade.
- Rename: Action rendering method
text
toplain_text
. - Update: use of
number_to_currency
now returns a String instead of writing to the view directly. - Delete:
config/static_file_handler.cr
. TheLucky::StaticFileHandler
no longer has config settings. - Add: a new
Lucky::LogHandler
configure to the bottom ofconfig/logger.cr
. - Update:
Avram::Repo.configure
toAvram.configure
inconfig/logger.cr
.
config/logger.cr
require "file_utils"
logger =
if Lucky::Env.test?
# Logs to `tmp/test.log` so you can see what's happening without having
# a bunch of log output in your specs results.
FileUtils.mkdir_p("tmp")
Dexter::Logger.new(
io: File.new("tmp/test.log", mode: "w"),
level: Logger::Severity::DEBUG,
log_formatter: Lucky::PrettyLogFormatter
)
elsif Lucky::Env.production?
# This sets the log formatter to JSON so you can parse the logs with
# services like Logentries or Logstash.
#
# If you want logs like in development use `Lucky::PrettyLogFormatter`.
Dexter::Logger.new(
io: STDOUT,
level: Logger::Severity::INFO,
log_formatter: Dexter::Formatters::JsonLogFormatter
)
else
# For development, log everything to STDOUT with the pretty formatter.
Dexter::Logger.new(
io: STDOUT,
level: Logger::Severity::DEBUG,
log_formatter: Lucky::PrettyLogFormatter
)
end
Lucky.configure do |settings|
settings.logger = logger
end
Lucky::LogHandler.configure do |settings|
# Skip logging static assets in development
if Lucky::Env.development?
settings.skip_if = ->(context : HTTP::Server::Context) {
context.request.method.downcase == "get" &&
context.request.resource.starts_with?(/\/css\/|\/js\/|\/assets\//)
}
end
end
Avram.configure do |settings|
settings.logger = logger
end
- Update:
script/setup
to include the new postgres checks.
# This must go *after* the 'shards install' step
+ printf "\n▸ Checking that postgres is installed\n"
+ check_postgres | indent
+ printf "✔ Done\n" | indent
+ printf "\n▸ Verifying postgres connection\n"
+ lucky db.verify_connection | indent
printf "\n▸ Setting up the database\n"
lucky db.create | indent
- Add: a new
AppDatabase
class insrc/app_database.cr
that inherits fromAvram::Database
.
class AppDatabase < Avram::Database
end
- Add:
require "./app_database"
tosrc/app.cr
right below therequire "./shards"
. - Rename:
Avram::Repo.configure
toAppDatabase.configure
inconfig/database.cr
. - Add:
Avram.configure
block.
config/database.cr
database_name = "..."
AppDatabase.configure do |settings|
if Lucky::Env.production?
settings.url = ENV.fetch("DATABASE_URL")
else
settings.url = ENV["DATABASE_URL"]? || Avram::PostgresURL.build(
database: database_name,
hostname: ENV["DB_HOST"]? || "localhost",
# Some common usernames are "postgres", "root", or your system username (run 'whoami')
username: ENV["DB_USERNAME"]? || "postgres",
# Some Postgres installations require no password. Use "" if that is the case.
password: ENV["DB_PASSWORD"]? || "postgres"
)
end
end
Avram.configure do |settings|
settings.database_to_migrate = AppDatabase
# this is moved from your old `Avram::Repo.configure` block.
settings.lazy_load_enabled = Lucky::Env.production?
end
- Move: the
settings.lazy_load_enabled
fromAppDatabase.configure
toAvram.configure
block. - Add: a
database
class method tosrc/models/base_model.cr
that returnsAppDatabase
.
abstract class BaseModel < Avram::Model
def self.database : Avram::Database.class
AppDatabase
end
end
-
Update:
Avram::Repo
toAppDatabase
inspec/setup/clean_database.cr
. -
Avram no longer automatically adds a timestamp and primary key to migrations. Add a primary key and timestamps to your old migrations.
Also note that the syntax for a UUID has changed. You use
primary_key id : UUID
instead of an option on 'create'def migrate create :users do # Add these to your 'create' statements in your migrations primary_key id : Int64 # Or 'UUID' if using UUID add_timestamps end end
-
Note: Avram now defaults primary keys to
Int64
instead ofInt32
. You can use thechange_type
macro to migrate your primary keys and foreign keys toInt64
if you need. Runlucky gen.migration UpdatePrimaryKeyTypes
.
class UpdatePrimaryKeyTypesV20190723233131 < Avram::Migrator::Migration::V1
def migrate
alter table_for(User) do
change_type id : Int64
end
alter table_for(Post) do
change_type id : Int64
change_type user_id : Int64
end
end
end
- Update: models now default the primary key to
Int64
. This can be overridden if your tables uses a different column type for your primary keys, such as Int32 or UUID
abstract class BaseModel < Avram::Model
macro default_columns
primary_key id : UUID
timestamps
end
end
This also means that any model that uses UUID
for a primary key can remove the primary_key_type
option
class User < BaseModel
# 0.16 and earlier
table :users, primary_key_type: :uuid do
column email : String
end
# Now with 0.17 it will use the 'default_columns' from the 'BaseModel'
table :users do
column email : String
end
end
- Rename:
Query.new.destroy_all
toQuery.truncate
. (e.g.UserQuery.new.destroy_all
=>UserQuery.truncate
) - Rename: all association query methods from the association name to
where_{association_name}
. (e.g.UserQuery.new.posts
=>UserQuery.new.where_posts
) - Update: all association query methods no longer take a block. Pass the query in as an argument. (e.g.
UserQuery.new.posts { |post_query| }
=>UserQuery.new.where_posts(PostQuery.new)
) - Update:
where_{association_name}
methods no longer need to be preceded by ajoin_{assoc}
, unless you need a custom join (i.e.left_join_{assoc}
). If you use a custom join, you will need to add theauto_inner_join: false
option to yourwhere_{assoc}
method.
- Rename: the
src/forms
directory tosrc/operations
. - Update:
require "./forms/mixins/**"
andrequire "./forms/**"
torequire "./operations/mixins/**"
andrequire "./operations/**"
respectively insrc/app.cr
- Rename:
BaseForm
toSaveOperation
insrc/operations
. (e.g.User::BaseForm
=>User::SaveOperation
) - Rename:
fillable
topermit_columns
- Rename: form class names to new naming convention. (e.g.
class UserForm < User::SaveOperation
=>class SaveUser < User::SaveOperation
). This step is optional, but still recommended to avoid future confusion. - Rename:
Avram::VirtualForm
toAvram::Operation
. - Rename: virtual form class names to new naming convention VerbNoun. (e.g.
class SignInForm < Avram::Operation
=>class SignInUser < Avram::Operation
). - Rename:
virtual
toattribute
. - Update: all
SaveOperation
classes to callbefore_save prepare
. Theprepare
method is no longer called by default, which allows you to rename this method as well. - Update:
FillableField
toPermittedAttribute
insrc/components/shared/
. Checkfield.cr
andfield_errors.cr
. - Update: all authentic classes and modules to use new operation setup. This may require renaming some files to fit the
VerbNoun
verb_noun.cr
convention.
Files in src/operations/
# src/operations/mixins/password_validations.cr
module PasswordValidations
+ macro included
+ before_save run_password_validations
+ end
#...
end
# src/operations/request_password_reset.cr
- class RequestPasswordReset < Avram::VirtualForm
+ class RequestPasswordReset < Avram::Operation
#...
end
# src/operations/reset_password.cr
- def prepare
- run_password_validations
+ before do
Authentic.copy_and_encrypt password, to: encrypted_password
# src/operations/sign_in_user.cr
- class SignInUser < Avram::VirtualOperation
+ class SignInUser < Avram::Operation
# src/operations/sign_up_user.cr
- def prepare
+ before_save do
validate_uniqueness_of email
- run_password_validations
- Update
sign_in_user.cr
to match the new template. - Rename the
FindAuthenticatable
mixin toUserFromEmail
, again the Lucky CLI template is a helpful guide.
- Upgrade to crystal 0.30.0
No updates to Lucky itself are required. There may be Crystal 0.30.0 related changes you may need to make.
- Upgrade to crystal 0.29.0
- Upgrade Lucky CLI (macOS)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date. Requires 0.29.0
brew upgrade lucky
-
Upgrade Lucky CLI (Linux)
-
Update
.crystal-version
to0.29.0
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/getting-started/installing#on-linux
-
Update versions in
shard.yml
- Lucky should be
~> 0.15
- Lucky should be
-
Run
shards update
-
Rename
src/server.cr
tosrc/start_server.cr
. -
Edit
src/start_server.cr
by changingapp
toapp_server
andApp
toAppServer
.- delete the line that starts with
puts "Listening on
-
Update
src/{your app name}.cr
to require./start_server
-
Rename
src/dependencies.cr
tosrc/shards.cr
-
Move the
App
class to a new file insrc/app_server.cr
-
Rename
App
toAppServer
and renameLucky::BaseApp
toLucky::BaseAppServer
in your newsrc/app_server.cr
-
Update
src/app.cr
to require new./app_server
file -
Update
src/app.cr
to require new./shards
file -
Replace usages of
Lucky::Action::Status::
with the respective crystalHTTP::Status::
- Upgrade to crystal 0.28.0
- Create new file
config/force_ssl_handler.cr
with the following content:
Lucky::ForceSSLHandler.configure do |settings|
settings.enabled = Lucky::Env.production?
end
- Upgrade Lucky CLI (macOS)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date. Requires 0.27.2
brew upgrade lucky
-
Upgrade Lucky CLI (Linux)
-
Update
.crystal-version
to0.27.2
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/installing/#install-lucky
-
Update versions in
shard.yml
- Lucky should be
~> 0.13
- LuckyFlow should be
~> 0.4
- Authentic should be
~> 0.3
- Lucky should be
-
Run
shards update
-
Find and replace
LuckyRecord
withAvram
-
Add
Lucky::AssetHelpers.load_manifest
belowrequire "dependencies"
insrc/app.cr
for browser apps. Skip for API only apps. -
Query#preload
with a query now includes the association name ->Query#preload_{{ assoc_name }}
-
Remove
unexpose
andunexpose_if_exposed
from your actions. Pages now ignore unused exposures so these methods have been removed. -
Change
require "lucky_record"
torequire "avram"
insrc/dependencies
-
Rename
config/log_handler.cr
toconfig/logger.cr
-
Replace
config/logger.cr
with this:
require "file_utils"
logger =
if Lucky::Env.test?
# Logs to `tmp/test.log` so you can see what's happening without having
# a bunch of log output in your specs results.
FileUtils.mkdir_p("tmp")
Dexter::Logger.new(
io: File.new("tmp/test.log", mode: "w"),
level: Logger::Severity::DEBUG,
log_formatter: Lucky::PrettyLogFormatter
)
elsif Lucky::Env.production?
# This sets the log formatter to JSON so you can parse the logs with
# services like Logentries or Logstash.
#
# If you want logs like in development use `Lucky::PrettyLogFormatter`.
Dexter::Logger.new(
io: STDOUT,
level: Logger::Severity::INFO,
log_formatter: Dexter::Formatters::JsonLogFormatter
)
else
# For development, log everything to STDOUT with the pretty formatter.
Dexter::Logger.new(
io: STDOUT,
level: Logger::Severity::DEBUG,
log_formatter: Lucky::PrettyLogFormatter
)
end
Lucky.configure do |settings|
settings.logger = logger
end
Avram::Repo.configure do |settings|
settings.logger = logger
end
-
If using
is
in queries, rename the calls toeq
-
App in
src/app.cr
should now inherit fromLucky::BaseApp
. See the changes you need to make. -
Move
bin/setup
toscript/setup
-
In your
README
replacebin/setup
withscript/setup
-
Replace
bin/lucky
in your.gitignore
with just/bin/
. Lucky projects should now put bash scripts in/script
. Binaries go in/bin/
and are ignored. -
id
in actions usingroute
now have the underscored version of the resource name prepended. You'll need to rename yourid
calls to<resource_name>_id
.
# Example from v0.12
class Users::Show < BrowserAction
route do
# Using the 'id' param
UserQuery.find(id)
end
end
# Would now be
class Users::Show < BrowserAction
route do
# Now it is 'user_id'
UserQuery.find(user_id)
end
end
-
Make changes to laravel.mix
-
Make changes to package.json
-
Run
yarn install
And you should now be good to go!
- Upgrade Lucky CLI (macOS)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date. Requires 0.27
brew upgrade lucky
- Upgrade Lucky CLI (Linux)
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/installing/#install-lucky
Use your package manager to update Crystal to v0.27
-
In
db/migrations
, changeLuckyMigrator::Migration
->LuckyRecord::Migrator::Migration
for every migration -
Remove
lucky_migrator
fromshard.yml
-
Remove
lucky_migrator
fromsrc/dependencies
-
Remove the
LuckyMigrator.configure
block fromconfig/database.cr
-
Configuration now requires passing an argument. Find and replace
.configure do
with.configure do |settings|
in all files inconfig
-
Update
config/session.cr
-
Change
Lucky::Session::Store.configure
toLucky::Session.configure do |settings|
-
Change your session key because signing/encryption has changed. For example: add
_0_12_0
to the end of the key. -
Remove
settings.secret = Lucky::Server.settings.secret_key_base
-
-
If using
cookies[]
anywhere in your app, change the key you use. Lucky now signs and encrypts all cookies. Old cookies will not decrypt properly. -
Change
session[]=
andcookies[]=
tosession|cookies.set|get
-
Change
session|cookies.destroy
tosession/cookies.clear
-
cookies.unset(:key)
anddelete.unset(:key)
should becookies|session.delete(:key)
-
Remove
unexpose current_user
fromsrc/actions/home/index.cr
-
Query#count
has been renamed toQuery#select_count
. For example:UserQuery.new.count
is nowUserQuery.new.select_count
-
Change
flash.danger
toflash.failure
in your actions. -
Update
Lucky::Flash::Handler
toLucky::FlashHandler
insrc/app.cr
-
Update usages of
Lucky::Response
toLucky::TextResponse
-
Update usages of
LuckyInflector::Inflector
toWordsmith::Inflector
-
Remove
config/session.cr
and copyconfig/cookies.cr
-
Replace
config/email.cr
with this one. -
Add this line to
spec_helper.cr
(around line 19) ->LuckyRecord::Migrator::Runner.new.ensure_migrated!
-
In
config/server.cr
, copy the new block starting atline 15
. -
Update shard versions in
shard.yml
:- Lucky
~> 0.12
- LuckyRecord
~> 0.7
- Authentic
~> 0.2
- LuckyFlow
~> 0.3
- Lucky
-
Change
.crystal-version
to0.27.0
-
Run
shards update
to install the new shards
- Upgrade Lucky CLI (macOS)
brew update
brew upgrade crystal-lang # Make sure you're up-to-date
brew upgrade lucky
- Upgrade Lucky CLI (Linux)
Remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/installing/#install-lucky
Use your package manager to update Crystal to v0.25
-
Update
.crystal-version
to0.25.0
-
Change
crystal deps
toshards install
inbin/setup
-
Update
lucky_flow
andlucky_migrator
inshard.yml
lucky_flow
should now be0.2
lucky_migrator
should now be0.6
-
Remove any cached shards: rm -rf ~/.cache/shards
This is to address a bug in shards: crystal-lang/shards#211
-
Run
shards update
-
Find all instances of
nested_action
and replace withnested_route
-
Find all instances of
action
and replace withroute
in your actionsTo make it easier to only change the right thing, search for
action do
and replace withroute do
. This will make it fairly easy to find and replace across your whole project. -
Move static assets from
static/assets
topublic/assets
-
Move
static/js
tosrc/js
-
Move
static/css
tosrc/css
-
Remove
/public
from.gitignore
-
Add these to
.gitignore
/public/mix-manifest.json
/public/js
/public/css
-
Update
src/app.cr
lines:- Remove host and port: https://github.com/luckyframework/lucky_cli/blob/ce677b8aefbbef2f06587d835795cbb59c5801dd/src/web_app_skeleton/src/app.cr.ecr#L25
- Add
bind_tcp
with host and port: https://github.com/luckyframework/lucky_cli/blob/ce677b8aefbbef2f06587d835795cbb59c5801dd/src/web_app_skeleton/src/app.cr.ecr#L50
-
Update webpack config to match this: https://github.com/luckyframework/lucky_cli/blob/ce677b8aefbbef2f06587d835795cbb59c5801dd/src/browser_app_skeleton/webpack.mix.js#L12-L37
-
Calls to the
asset
method no longer require prefixing/assets
. You may not be using this. The compiler will complain and help you find the right asset if you need to update this.
Note: Lucky skipped version 0.9 so that Lucky and Lucky CLI are on the same version.
- Upgrade Lucky CLI
On macOS:
brew update
brew upgrade crystal-lang # Make sure you're up-to-date
brew upgrade lucky
If you are on Linux, remove the existing Lucky binary and follow the Linux instructions in this section https://luckyframework.org/guides/installing/#install-lucky
- View the upgrade diff and make changes to your app
In previous upgrade guides (below) every change is listed individually. This was time consuming and error-prone. Now, you can view all changes in this GitHub commit.
-
Ensure node version is at least 6.0
node -v
. Install a newer version if yours is older. -
Move files in
src/pipes
tosrc/actions/mixins
-
Change
allow
tofillable
in forms -
Change
allow_virtual
tovirtual
in forms -
Run
shards update
-
Run
bin/setup
to run new migrations, Laravel Mix and seeds file
If you have any problems or want to add extra details please open an issue or Pull Request. Thank you!
- Upgrade Lucky CLI
On macOS:
brew update
brew upgrade crystal-lang
brew upgrade lucky
If you are on Linux, remove the existing Lucky binary and follow the Linux instructions in this section: https://luckyframework.org/guides/installing/#install-lucky
- Update dependencies in
shard.yml
dependencies:
lucky:
github: luckyframework/lucky
version: "~> 0.8.0"
lucky_migrator:
github: luckyframework/lucky_migrator
version: ~> 0.4.0
Then run shards update
- Update
config/server.cr
You can probably copy this as-is, but if you have made customizations to your
config/server.cr
then you'll need to customize this:
Lucky::Server.configure do |settings|
if Lucky::Env.production?
settings.secret_key_base = secret_key_from_env
settings.host = "0.0.0.0"
settings.port = ENV["PORT"].to_i
else
settings.secret_key_base = "<%= secret_key_base %>"
# Change host/port in config/watch.yml
# Alternatively, you can set the PORT env to set the port
settings.host = Lucky::ServerSettings.host
settings.port = Lucky::ServerSettings.port
end
end
private def secret_key_from_env
ENV["SECRET_KEY_BASE"]? || raise_missing_secret_key_in_production
end
private def raise_missing_secret_key_in_production
raise "Please set the SECRET_KEY_BASE environment variable. You can generate a secret key with 'lucky gen.secret_key'"
end
- Add
config/watch.yml
This is used by the watcher so it knows what port the server is running on.
host: 0.0.0.0
port: 5000
- Update
config/database.cr
Put this inside of the LuckyRecord::Repo.configure do |settings|
block:
# In development and test, raise an error if you forget to preload associations
settings.lazy_load_enabled = Lucky::Env.production?
See a full example here: https://github.com/luckyframework/lucky_cli/blob/a25472cc7461b1803735d086e57a632f92f93a1c/src/web_app_skeleton/config/database.cr.ecr
- You will need to preload associations now:
This will make N+1 queries a thing of the past.
# Will now raise a runtime error in dev/test
post = PostQuery.new.find(id)
post.comments # Must preload comments
# Now, you need to preload the comments
post = PostQuery.new.preload_comments.find(id)
post.comments
- Rename
field
tocolumn
in your models. For example
class Post < BaseModel
table :posts do
column title : String # was "field title : String" previously
end
end
- Optionally include
responsive_meta_tag
inMainLayout
You can include this in head
to make your app layout responsive.
-
Change
abstract def inner
toabstract def content
inMainLayout
-
Change method call to
inner
tocontent
in the render method ofMainLayout
-
Change instances of
def inner
todef content
in Pages -
Change form
needs
to useon: :create
needs
in forms should now use on: :save
if you want the old behavior.
See https://luckyframework.org/guides/saving-with-forms/#passing-extra-data-to-forms for more info
- Must pass extra params using
create
orupdate
You can no longer pass params to Form#new
. You must pass them in the
create
or update
.
UserForm.new(name: "Jane").save!
UserForm.create!(name: "Jane")
More info at https://luckyframework.org/guides/saving-with-forms/#passing-data-without-route-params
-
Change calls from
form.save_succeeded?
toform.saved?
-
Trap int in src/server.cr
Add this to your src/server.cr
before server.listen
Signal::INT.trap do
server.close
end
- Add
bin/lucky/
to.gitignore
# Add to .gitignore
bin/lucky/
- Add nice HTML error page
Copy contents of the linked file to src/pages/errors/show_page.cr
https://github.com/luckyframework/lucky_cli/blob/a25472cc7461b1803735d086e57a632f92f93a1c/src/web_app_skeleton/src/pages/errors/show_page.cr
- Add default
Error::ShowSerializer
This is used for serializing errors to JSON. Add this to
src/serializers/errors/show_serializer.cr
# This is the default error serializer generated by Lucky.
# Feel free to customize it in any way you like.
class Errors::ShowSerializer < Lucky::Serializer
def initialize(@message : String, @details : String? = nil)
end
def render
{message: @message, details: @details}
end
end
- Update
Errors::Show
action
The error handling action now supports more errors and renders better output.
Copy the contents of the linked file to src/actions/errors/show.cr
https://github.com/luckyframework/lucky_cli/blob/a25472cc7461b1803735d086e57a632f92f93a1c/src/web_app_skeleton/src/actions/errors/show.cr
- Require serializers
Add the following to src/app.cr
.
require "./serializers/**"
- Update to Crystal v0.24.1. Lucky will fail on earlier versions
brew update
brew upgrade crystal-lang
brew upgrade lucky
If you are on Linux, remove the existing Lucky binary and follow the Linux instructions in this section: https://luckyframework.org/guides/installing/#install-lucky
- Update dependencies in
shard.yml
dependencies:
lucky:
github: luckyframework/lucky
version: "~> 0.7.0"
lucky_migrator:
github: luckyframework/lucky_migrator
version: ~> 0.4.0
Then run shards update
- Configure the domain to use for the RouteHelper:
# Add to config/route_helper.cr
Lucky::RouteHelper.configure do |settings|
if Lucky::Env.production?
# The APP_DOMAIN is something like https://myapp.com
settings.domain = ENV.fetch("APP_DOMAIN")
else
settings.domain = "http:://localhost:3001"
end
end
- Add
csrf_meta_tags
to yourMainLayout
# src/pages/main_layout.cr
# Somewhere in the head tag:
csrf_meta_tags
- Remove
needs flash
fromMainLayout
# Delete this line
needs flash : Lucky::Flash::Store
- Remove
expose flash
fromBrowserAction
and add forgery protection
# src/actions/browser_action.cr
abstract class BrowserAction < Lucky::Action
include Lucky::ProtectFromForgery
end
- Change
Shared::FlashComponent
to get the flash from@context
# src/components/shared/flash_component.cr
# Change this:
@flash.each
# To:
@context.flash.each
- Add
*.dwarf
to the .gitignore
# Add to .gitignore
*.dwarf