These are notes - so they might be partly or fully incorrect. This is just me jotting down things to wrap my head around it...
Models describe what your object is.
Operations are objects that provide an interface on how your applications interact with the model. This is a bit different than, say, Rails' Active Record (at least the last time I looked at it). If you need to create a custom validation, callback, restrictions on what fields can be updated, they go here.
I'm creating a model called Post (pluralized to Posts in the DB). Lucky automatically creates created_at and updated_at fields when you create a new model. It will also create a Save Operation called SavePost which inherits from Post::SaveOperation. The default will look like:
class SavePost < Post::SaveOperation permit_columns title, body end
Notice the only permitted columns you can update are title and body (which were defined when I created the model). I can't touch created_at or updated_at - at least without specifying these columns (not that you'd really want to - but this is just an example).
Queries are objects that hold your custom queries you define for your models.
The View layer has three parts - Pages, Components, and Layouts
Pages are how you present the content to the user. The default method in lucky is that all of your views are written in Crystal like this:
def render_posts ul do posts.each do |post| li do link post.title, Posts::Show.with(post) end end end end
Notice - no HTML. You can swap this out for something else but it generally works pretty well, once you get the hang of writing crystal instead of HTML. It reminds me a lot of (IIRC) Smalltalk's Seaside framework.
Components are little chunks of shareable objects. Instead of having to add a header and footer into each page, you can create a component.
Layouts let you define a shared structure throughout your site. This is fairly obvious. But in the getting-started tutorial on the Lucky site, you'll do an example where you create a Home page which inherits from a layout. You then add a footer and navbar component to the layout and the content from the Page is then parsed into the final document:
def render html_doctype html class: "h-100", lang: "en" do mount Shared::LayoutHead, page_title: page_title body class: "d-flex flex-column h-100" do mount Shared::Navbar mount Shared::FlashMessages, context.flash main class: "flex-shrink-0" do content end mount Shared::Footer end end end
Your controllers are called Actions - each action has a separate class in distinct file. Your Actions control how resources are called and how the response is presented to the user.