Lucky

一个功能齐全的 Crystal web 框架,为您捕获漏洞,运行速度令人难以置信,并帮助您编写持久的代码。「A full-featured Crystal web framework that catches bugs for you, runs incredibly fast, and helps you write code that lasts.」

Github星跟踪图

github banner-short

Version
License

API Documentation Website
Lucky Guides Website

Discord

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.

Coming from Rails?

Try Lucky

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.

Installing Lucky

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

Keep up to date by following @luckyframework on Twitter.

Documentation

API (master)

What's it look like?

JSON endpoint:

class Api::Users::Show < ApiAction
  route do
    json user_json
  end
  private def user_json
    user = UserQuery.find(user_id)
    {name: user.name, email: user.email}
  end
end
  • route sets up a route for "/api/users/:user_id" automatically.
  • If you want you can set up custom routes like get "sign_in" for non REST routes.
  • A user_id method is generated because there is a user_id route parameter.
  • Use json to render JSON. Extract
    serializers

    for reusable JSON responses.

Database models

# Set up the model
class User < BaseModel
  table :users do
    column last_active_at : Time
    column last_name : String
    column nickname : String?
  end
end
  • Sets up the columns that you’d like to use, along with their types
  • You can add ? to the type when the column can be nil . Crystal will then
    help you remember not to call methods on it that won't work.
  • Lucky will set up presence validations for required fields
    (last_active_at and last_name since they are not marked as nilable).

Querying the database

# 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. Inherit
    from it to customize queries.
  • Set up named scopes with instance methods.
  • Lucky sets up methods for all the columns so that if you mistype a column
    name it will tell you at compile-time.
  • Use the lower method on a String column to make sure Postgres sorts
    everything in lowercase.
  • Use gt to get users last active greater than 1 week ago. Lucky has lots
    of powerful abstractions for creating complex queries, and type specific
    methods (like lower).

Rendering HTML:

class Users::Index < BrowserAction
  route 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 users
    of the type UserQuery.
  • If you forget to pass something that a page needs, it will let you know at
    compile time. Fewer bugs and faster debugging.
  • Write tags with Crystal methods. Tags are automatically closed and
    whitespace is removed.
  • Easily extract named methods since pages are made of regular classes and
    methods. This makes your HTML pages incredibly easy to read.
  • Link to other pages with ease. Just use the action name: Users::New. Pass
    params using with: Users::Show.with(user.id). No more trying to remember path
    helpers and whether the helper is pluralized or not - If you forget to pass a
    param to a route, Lucky will let you know at compile-time.
  • Since we defined column nickname : String? as nilable, Lucky would fail
    to compile the page if you just did text user.nickname since it disallows
    printing nil. So instead we add a fallback "No Nickname". No more
    accidentally printing empty text in HTML!

Testing

You need to make sure to install the Crystal dependencies.

  1. Run shards install
  2. Run crystal spec from the project root.

Contributing

See CONTRIBUTING.md

Lucky to have you!

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.

Contributors

Thanks & attributions

  • SessionHandler, CookieHandler and FlashHandler are based on Amber. Thank you to the Amber team!
  • Thanks to Rails for inspiring many of the ideas that are easy to take for
    granted. Convention over configuration, removing boilerplate, and most
    importantly - focusing on developer happiness.
  • Thanks to Phoenix, Ecto and Elixir for inspiring Avram's save operations,
    Lucky's single base actions and pipes, and focusing on helpful error
    messages.
  • lucky watch based heavily on Sentry. Thanks @samueleaton!

主要指标

概览
名称与所有者luckyframework/lucky
主编程语言Crystal
编程语言Crystal (语言数: 4)
平台Docker, Linux, Mac
许可证MIT License
所有者活动
创建于2017-01-06 20:58:57
推送于2025-04-10 20:23:11
最后一次提交2022-02-12 19:25:36
发布数80
最新版本名称v1.3.0 (发布于 )
第一版名称v0.2.0 (发布于 2017-06-16 14:13:24)
用户参与
星数2.6k
关注者数44
派生数162
提交数1.2k
已启用问题?
问题数844
打开的问题数95
拉请求数831
打开的拉请求数3
关闭的拉请求数51
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?