Skip to content

Releases: martenframework/marten

0.6.3

29 Mar 23:34
9e7d113

Choose a tag to compare

Marten 0.6.3 fixes a couple of bugs.

Changes

  • Fix array schema field deserialization logic for arrays of values extracted from JSON objects.
  • Fix a possible crash with the Method Override middleware on requests with empty bodies.

0.6.2

09 Dec 23:58
b455179

Choose a tag to compare

Marten 0.6.2 fixes a couple of bugs and a security issue.

Changes

  • Fix possible migration issues when changing the values of an enum field with PostgreSQL.
  • Fix child records not being cascade deleted when parent records using multi table inheritance are destroyed.

0.6.1

11 Oct 23:55
1160f0c

Choose a tag to compare

Marten 0.6.1 fixes a couple of bugs and a security issue.

Changes

  • Fix inconsistent results when joining multiple reverse relations corresponding to child models (multi-table inheritance) in the same query.
  • Fix config/locales translations configuration not working when the root_path setting is defined.
  • Make sure that Time and Time::Span object attributes can be manipulated in templates.

0.6.0

03 Aug 18:22
55faf93

Choose a tag to compare

Marten 0.6 is here! This major version brings significant enhancements, including localized routes, annotations, array schema fields, and image fields for models and schemas. These features make building apps with Marten smoother and more flexible.

Requirements and compatibility

  • Crystal: 1.15, 1.16, and 1.17.
  • Databases:
    • MariaDB 10.5 and higher.
    • MySQL 8.0.11 and higher.
    • PostgreSQL 14 and higher.
    • SQLite 3.31.0 and higher.

New features

Localized routes

Marten now provides the ability to define localized routes through the use of two mechanisms: automatically adding locale prefixes to routes and activating the appropriate locale based on the prefix, and translating the routes themselves. These mechanisms can be used independently or in combination.

For example, the following routes map defines routes that will be prefixed by the currently activated locale and whose paths will be translated using the considered project's translations:

ARTICLE_ROUTES = Marten::Routing::Map.draw do
  path t("routes.articles.list"), ArticlesHandler, name: "list"
  path t("routes.articles.create"), ArticleCreateHandler, name: "create"
  path t("routes.articles.detail"), ArticleDetailHandler, name: "detail"
  path t("routes.articles.update"), ArticleUpdateHandler, name: "update"
  path t("routes.articles.delete"), ArticleDeleteHandler, name: "delete"
end

Marten.routes.draw do
  localized do
    path t("routes.landing"), LandingPageHandler, name: "landing"
    path t("routes.articles.prefix"), ARTICLE_ROUTES, name: "articles"
  end
end

As highlighted above, the use of routes prefixed with locales can be activated by wrapping route paths by a call to the #localized method. Route path translations can be defined using the #t method, which assigns a translation key to each route (this key is then dynamically used to generate the route's path based on the active locale).

With the routes map defined above, generated routes are fully localized and vary based on the currently activated locale:

I18n.activate("en")
Marten.routes.reverse("landing")         # => "/en/landing"
Marten.routes.reverse("articles:create") # => "/en/articles/create"

I18n.activate("fr")
Marten.routes.reverse("landing")         # => "/fr/accueil"
Marten.routes.reverse("articles:create") # => "/fr/articles/creer"

Please refer to Localized routes to learn more about this new capability.

Annotations

Marten now lets you annotate query sets with aggregated data. This is useful when you need to "retain" aggregated values for each record in a query set (possibly for further filtering or for making use of the aggregated values when dealing with individual records). This can be achieved by using the #annotate method.

For example:

# Annotate the query set with the number of articles for each author.
Author.all.annotate { count(:articles) }

# Get all the authors that have more than 10 articles.
Author.all.annotate { count(:articles) }.where(articles_count__gt: 10)

# Order all the authors by the number of articles they have.
Author.all.annotate { count(:articles) }.order(:articles_count)

# Access the annotated values for each author.
authors = Author.all.annotate { count(:articles) }
authors.each do |author|
  puts author.name
  puts author.annotations["articles_count"]
end

Please refer to the Aggregations section to learn more about this new capability.

Array schema field

Marten now lets you define array schema fields that allow validating lists of values, with each value subject to the validation rules of an array member field (such as string, int, or any other existing schema field type).

For example, the following schema allows validating lists of string values whose sizes must not be greater than 10:

class TestSchema < Marten::Schema
  field :values, of: :string, max_size: 10
end

As highlighted by the above example, the type of the underlying array member field must be specified through the use of an of option, which should reference an existing schema field type (such as string, enum, etc).

Please refer to the schema field reference to learn more about array fields.

Image fields for models and schemas

It is now possible to define image fields in models and schemas, which allow you to store or validate files that are indeed images. This capability requires the use of the crystal-vips shard.

For example:

class ImageAttachment < Marten::Model
  field :id, :big_int, primary_key: true, auto: true
  field :uploaded_file, :image, blank: false, null: false
end

attachment = ImageAttachment.first!
attachment.uploaded_file            # => #<Marten::DB::Field::File::File:0x102dd0ac0 ...>
attachment.uploaded_file.attached?  # => true
attachment.uploaded_file.name       # => "test.png"
attachment.uploaded_file.size       # => 5796929
attachment.uploaded_file.url        # => "/media/test.png"

Minor features

Models and databases

  • Query sets now support XOR operations when performing complex queries involving q expressions. Additionally, combining query sets using the XOR operator (^) is now also supported (see #^ (XOR)).
  • A new slugify option was added to slug model fields in order to make it possible to automatically generate a slug value from another local model field.
  • Query pages (instances of Marten::DB::Query::Page) now expose a #pages_count method that allows to get the total number of pages.
  • Related objects are now automatically loaded when accessing backward relations (such as backward many-to-one relations or backward one-to-one relations).
  • The ability to retrieve specific records by using raw SQL predicates was introduced. See Fetching single records with raw SQL predicates to learn more about this new capability.
  • The #prefetch query set method now provides an optional query_set argument, allowing you to specify a custom query set for retrieving prefetched records.
  • A new #total_count method was added to the paginator and page objects to make it possible to retrieve the total number of records in the paginated query set, without applying pagination.

Handlers and HTTP

Read more

0.5.7

30 Jun 14:28
fb94a3a

Choose a tag to compare

Marten 0.5.7 fixes a couple of bugs and a security issue.

Changes

  • Fix #add method in many-to-many query sets to work with records that use a primary key field other than id.
  • Fix scope logic leaking between models when scopes had the same name.

0.5.6

15 May 02:42
ade7000

Choose a tag to compare

Marten 0.5.6 fixes a couple of bugs and a security issue.

Changes

  • Make sure bound field required state is exposed in templates.
  • Fix possible JSON::ParseException exception when processing application/json requests with an empty body.
  • Fix inability to manually set auto-incremented primary key on create.

0.5.5

08 Feb 01:30
c1830ec

Choose a tag to compare

Marten 0.5.5 fixes a couple of bugs and a security issue.

Changes

  • Fix possible compilation error for json fields defined without additional options.
  • Fix incorrect operations created when generating migrations for models in which multiple columns were renamed.
  • Make sure that the strings that are translated in templates (when using the translate tag) are automatically escaped (see Auto-escaping).

0.5.4

24 Nov 21:09
2d67b11

Choose a tag to compare

Marten 0.5.4 fixes a couple of bugs.

Bug fixes

  • Fix possible undefined constant compilation error when using file schema fields.
  • Fix CSRF token request data parameter not being used when the method of POST requests is overridden with the Method Override middleware.

0.5.3

06 Oct 19:27
dd361be

Choose a tag to compare

Marten 0.5.3 fixes a couple of bugs.

Bug fixes

  • Fix query prefetcher not systematically using unscoped queries when prefetching relation records.
  • Fix possible case sensitivity issue when specifying HTTP method names supported by specific handlers.
  • Fix inconsistent callback name in the password update handler generated for the authentication application.

0.5.2

24 Aug 20:27
9675b2d

Choose a tag to compare

Marten 0.5.2 fixes a couple of bugs.

Bug fixes

  • Fix text template name of emails generated through the use of the email generator.
  • Fix non-existing error when the new management command was used to generate an app structure with the --with-auth option.
  • Fix missing "emails" folder requirement in projects generated with the new management command.
  • Fix how nested routes are displayed when invoking the routes management command.
  • Fix settings namespace generation for top-level Settings settings classes.