This new Lotus release is an important step towards 1.0!
In the past months we talked with people at conferences, meetups, events, you all are eagerly looking for a production ready version. This makes us proud of Lotus and we are determined to get there.
That's why we have decided to postpone a few announced features like WebSocket and experimental code reloading.
Let's have a look at what is shipped with this version.
Inês & Rosa (aka DEIGirls), are the Rails Girls Summer of Code students who worked on mailers.
During these three months, mentored by Trung Lê, they learned about Ruby, Lotus and they shipped their first gem:
This is a huge achievement for all of us!
We have introduced a generator, which creates a mailer, the test code and two associated templates for multipart delivery.
% bundle exec lotus generate mailer forgot_password create spec/bookshelf/mailers/forgot_password_spec.rb create lib/bookshelf/mailers/forgot_password.rb create lib/bookshelf/mailers/templates/forgot_password.txt.erb create lib/bookshelf/mailers/templates/forgot_password.html.erb
For simplicity, each mailer can handle only one use case (feature).
If in our application we need to send emails for several features like: "confirm your email address" or "forgot password", we will have
Mailers::ForgotPassword instead of a generic
UserMailer that manages all these use cases.
# lib/bookshelf/mailers/forgot_password.rb class Mailers::ForgotPassword include Lotus::Mailer from 'email@example.com' to 'firstname.lastname@example.org' subject 'Hello' end # Usage Mailers::ForgotPassword.deliver
Lotus data mapper supports the most common Ruby data type such as
Sometimes, this simple approach is not enough to solve the database impedance mismatch on types.
Imagine we have a
Book#tags, a collection of strings that we want to store as a Postgres array.
If we use
Array builtin type, our tags aren't properly translated into a format that is compatible with our column type.
The solution to this problem is to define a custom coercer.
# lib/ext/pg_array.rb require 'lotus/model/coercer' require 'sequel/extensions/pg_array' class PGArray < Lotus::Model::Coercer def self.dump(value) ::Sequel.pg_array(value, :varchar) end def self.load(value) ::Kernel.Array(value) unless value.nil? end end
# lib/bookshelf.rb require_relative './ext/pg_array' # ... Lotus::Model.configure do # ... mapping do # ... collection :articles do attribute :id, Integer attribute :tags, PGArray end end end.load!
When the powerful repositories API doesn't fit our needs, we can send raw command and queries to the database.
Until now there was a generic
.execute to use. Both the signature and the semantic of this method, became too complex, so we decided to add
It returns a raw dataset from the database.
# lib/bookshelf/repositories/book_repository.rb class BookRepository include Lotus::Repository def self.raw_all fetch("SELECT * FROM books") end def self.find_all_titles fetch("SELECT title FROM books").map do |book| book[:title] end end end
.execute send a raw command and return
# lib/bookshelf/repositories/book_repository.rb class BookRepository include Lotus::Repository def self.reset_download_count execute("UPDATE books SET download_count = 0") end end
Thanks to Theo Felippe for the MIME type detection work and to Wellington Santos for a better exception handling.
To Pascal Betz, José Mota, Alex Wochna and Khải Lê for their form helper enhancements, while Leonardo Saraiva wrote an expanded version of
default_format in favor of
We also introduced
default_response_format to force a MIME Type, without the need of specify it for each action.
It defaults to
:html, but if you are building a JSON API, you may find useful to set it to
# apps/web/application.rb # ... module Web class Application < Lotus::Application configure do # If you are using this: default_format :xml # Please rename into: default_request_format :xml end end end
Did you always wanted to play with Lotus but you keep saying: "I don't have time"?
As Lotus will approach to 1.0, we'll need your help, your feedback.. and your fun! So, here's the deal.. we're organizing a Hack Day later this year!
⬇️ If you want to get alerted, please consider to subscribe to our mailing list using the form below. ⬇️
Until then, happy hacking!