Lucky v0.15 is a big new release. Brand new class based UI components, lots of bug fixes, and support for Crystal 0.29. We are also releasing a brand new website to go with it.
Lucky 0.15.0 has been in the making for a few months and has lots of new goodies, bug fixes, and support for the newest version of Crystal (0.29.0)
We’re also releasing a brand new website along with this new version of Lucky.
We’ve totally revamped the Lucky website. Check it out:
And the new website uses Lucky instead of Middleman 🎉
Lucky 0.15 contains lots of bug fixes and improvements. We’d like to highlight a few of our favorite new features.
You can now use classes for components. You declare what the component needs and then you can mount it on a page.
This greatly simplifies code reuse, allows you to have named private methods, and makes testing a breeze
# lucky gen.component UserRow
class UserRow < BaseComponent
needs user : User
def render
div class: "user-row-style" do
h2 @user.name
end
end
end
Now we can use it in a page with mount
:
mount UserRow.new(UserQuery.first)
Or test it by rendering the component to a string:
user = UserQuery.first
html = UserRow.new(user.first).render_to_string
html.should contain user.name
There are now a bunch of new security headers that you can easily add and configure for your app. Check it out under our new security guide.
You can configure an asset host for asset paths. This makes it simple to use your CDN for fast content delivery.
Lucky::Server.configure do |settings|
if Lucky::Env.production?
settings.asset_host = "https://myfastcdn.com"
else
settings.asset_host = "/"
end
end
You can think of this like a “catch-all” route. If no other route matches in your application,
Lucky will run this as a last try. To use it, just create your action and use fallback
.
This can be a great way to have Lucky pass route handling over to your front-end framework!
class VueHandlerAction < BrowserAction
fallback do
if html?
html VueApp::IndexPage
else
raise Lucky::RouteNotFoundError.new(context)
end
end
end
Learn more about fallback routing
nilable_eq
Previously you could pass a nil
value when comparing values in a query.
The problem with this is that you may not be expecting to compare to nil
.
Now Lucky helps make this distinction clear by only allowing eq
for non-nil values
and using nilable_eq
for things that may be nil
. This will help catch subtle nil bugs.
# 'name' might be a String or Nil
name = ["John", nil].sample
# When using 'eq' Lucky will stop at compile time and tell
# you that you are comparing to a possible 'nil' value
UserQuery.new.name.eq(name)
We can make this work by using nilable_eq
or handling the nil
with
a conditional
name = ["John", nil].sample
UserQuery.new.name.nilable_eq(name)
# Or if we want to handle 'nil' differently
if name
UserQuery.new.name.eq(name)
else
raise "Oh no! There is no name"
end
Avram Boxes are how we generate test data. This release introduces sequence
for easily generating unique values.
class UserBox < Avram::Box
def initialize
# username-1, username-2, etc.
username sequence("username")
# email-1@example.com, email-2@example.com, etc.
email "#{sequence("email")}@example.com"
end
end
There are lots of other improvements and bug fixes in this release. Thanks to all our contributors that made this release possible!
We hope you love it!