A full-featured Crystal web framework that catches bugs for you, runs incredibly fast, and helps you write code that lasts.
MIT License
The goal: prevent bugs, forget about most performance issues, and spend more time on code instead of debugging and fixing tests.
In summary, make writing stunning web applications fast, fun, and easy.
Lucky has a fresh new set of guides that make it easy to get started.
Feel free to say hi or ask questions on our chat room.
Or you can copy a real working app with Lucky JumpStart.
To install Lucky, read the Installing Lucky guides for your Operating System. The guide will walk you through installing a command-line utility used for generating new Lucky applications.
Keep up to date by following @luckyframework on Twitter.
class Api::Users::Show < ApiAction
get "/api/users/:user_id" do
user = UserQuery.find(user_id)
json UserSerializer.new(user)
end
end
get "/sign_in"
for non REST routes.user_id
method is generated because there is a user_id
route parameter.json
to render JSON. Extract# Set up the model
class User < BaseModel
table do
column last_active_at : Time
column last_name : String
column nickname : String?
end
end
?
to the type when the column can be nil
. Crystal will thenlast_active_at
and last_name
since they are not marked as nilable).# 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
User::BaseQuery
is automatically generated when you define a model. Inheritlower
method on a String
column to make sure Postgres sortsgt
to get users last active greater than 1 week ago. Lucky has lotslower
).class Users::Index < BrowserAction
get "/users" do
users = UserQuery.new.sorted_by_last_name
render IndexPage, users: users
end
end
class Users::IndexPage < MainLayout
needs users : UserQuery
def content
render_new_user_button
render_user_list
end
private def render_new_user_button
link "New User", to: Users::New
end
private def render_user_list
ul class: "user-list" do
users.each do |user|
li do
link user.name, to: Users::Show.with(user.id)
text " - "
text user.nickname || "No Nickname"
end
end
end
end
end
needs users : UserQuery
tells the compiler that it must be passed usersUserQuery
.Users::New
. Passwith
: Users::Show.with(user.id)
. No more trying to remember pathcolumn nickname : String?
as nilable, Lucky would failtext user.nickname
since it disallowsnil
. So instead we add a fallback "No Nickname"
. No moreYou need to make sure to install the Crystal dependencies.
shards install
crystal spec
from the project root.See CONTRIBUTING.md
We love all of the community members that have put in hard work to make Lucky better. If you're one of those people, we want to give you a t-shirt!
To get a shirt, we ask that you have made a significant contribution to Lucky. This includes things like submitting PRs with bug fixes and feature implementations, helping other members work through problems, and deploying real world applications using Lucky!
To claim your shirt, fill in this form.
lucky watch
based heavily on Sentry. Thanks @samueleaton!