Releases: martenframework/marten
0.6.3
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
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
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/localestranslations configuration not working when theroot_pathsetting is defined. - Make sure that
TimeandTime::Spanobject attributes can be manipulated in templates.
0.6.0
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
endAs 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"]
endPlease 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
endAs 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
qexpressions. Additionally, combining query sets using the XOR operator (^) is now also supported (see#^ (XOR)). - A new
slugifyoption was added toslugmodel 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_countmethod 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
#prefetchquery set method now provides an optionalquery_setargument, allowing you to specify a custom query set for retrieving prefetched records. - A new
#total_countmethod 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
- Session stores now make it possible to easily configure when session entries expire through the use of the
#expires_at=,#expires_at_browser_close=, and#expires_in=methods. Please refer to Customizing session expiry times to learn more about this capability. - An alias for the
#reversehandler method (#url) was introduced. - A Referrer-Policy middleware was introduced to make it possible to automatically set the Referrer-Policy header in responses generated by handlers.
- A new
unsupported_http_method_strategysetting was introduced to make it possible to configure the strategy to use when processing unsupport...
0.5.7
0.5.6
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::ParseExceptionexception when processingapplication/jsonrequests with an empty body. - Fix inability to manually set auto-incremented primary key on create.
0.5.5
Marten 0.5.5 fixes a couple of bugs and a security issue.
Changes
- Fix possible compilation error for
jsonfields 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
translatetag) are automatically escaped (see Auto-escaping).
0.5.4
Marten 0.5.4 fixes a couple of bugs.
Bug fixes
- Fix possible undefined constant compilation error when using
fileschema 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
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
Marten 0.5.2 fixes a couple of bugs.
Bug fixes
- Fix text template name of emails generated through the use of the
emailgenerator. - Fix non-existing error when the
newmanagement command was used to generate an app structure with the--with-authoption. - Fix missing "emails" folder requirement in projects generated with the
newmanagement command. - Fix how nested routes are displayed when invoking the
routesmanagement command. - Fix settings namespace generation for top-level
Settingssettings classes.