Applications
Marten projects can be organized into logical and reusable components called "applications". These applications can contribute specific behaviors and abstractions to a project, including models, handlers, schemas, emails, and templates. They can be packaged and reused across various projects as well.
Overview
A Marten application is a set of abstractions (defined under a dedicated and unique folder) that provides some set of features. These abstractions can correspond to models, handlers, templates, schemas, emails, etc.
Marten projects always use one or many applications. Indeed, each Marten project comes with a default main application that corresponds to the standard src
folder: models, migrations, or other classes defined in this folder are associated with the main application by default (unless they are part of another explicitly defined application). As projects grow in size and scope, it is generally encouraged to start thinking in terms of applications and how to split models, handlers, or features across multiple apps depending on their intended responsibilities.
Another benefit of applications is that they can be packaged and reused across multiple projects. This allows third-party libraries and shards to easily contribute models, migrations, handlers, or templates to other projects.
Using applications
The use of applications must be manually enabled within projects: this is done through the use of the installed_apps
setting.
This setting corresponds to an array of installed app classes. Indeed, each Marten application must define a subclass of Marten::App
to specify a few things such as the application label (see Creating applications for more information about this). When those subclasses are specified in the installed_apps
setting, the applications' models, migrations, assets, and templates will be made available to the considered project.
For example:
Marten.configure do |config|
config.installed_apps = [
FooApp,
BarApp,
]
end
Adding an application class inside this array will have the following impact on the considered project:
- the models of this application and the associated migrations will be used
- the templates of the application will be made available to the templates engine
- the assets of the application will be made available to the assets engine
- the management commands defined by the application will be made available to the Marten CLI
The main application
The "main" application is a default application that is always implicitly used by Marten projects (which means that it does not appear in the installed_apps
setting). This application is associated with the standard src
folder: this means that models, migrations, assets, or templates defined in this folder will be associated with the main application by default. For example, models defined under a src/models
folder would be associated with the main application.
The main application is associated with the main
label. This means that models of the main application that do not define an explicit table name will have table names starting with main_
.
It should be noted that it is possible to create explicitly defined applications whose structures live under the src
folder as well: the abstractions (eg. models, migrations, etc) of these applications will be associated with them and not with the main application. This is because abstractions are always associated with the closest application in the files/folders structure.
In the end, the main application provides a convenient way for starting projects and prototyping without requiring to spec out how projects will be organized in terms of applications upfront. That being said, as projects grow in size and scope, it is really encouraged to start thinking in terms of applications and how to split abstractions and features across multiple apps depending on their intended responsibilities.
Order of installed applications
You should note that the order in which installed applications are defined in the installed_apps
setting can actually matter.
For example, a "foo" app might define a test.html
template, and a similar template with the exact same name might be defined by a "bar" app. If the "foo" app appears before the "bar" app in the array of installed apps, then requesting and rendering the test.html
template will actually involve the "foo" app's template only. This is because template loaders associated with app directories iterate over applications in the order in which they are defined in the installed apps array.
This is why it is always important to namespace abstractions, assets, templates, and locales when creating applications. Failing to do so exposes apps to conflicts with other applications' code. As such, in the previous example, the "foo" app should've defined a foo/test.html
template while the "bar" app should've defined a bar/test.html
template to avoid possible conflicts.
Creating applications
Creating applications can be done very easily through the use of the app
generator. For example:
marten gen app blog
Running such a command will add a new blog
application to the current project with the following structure:
src/blog
├── emails
├── handlers
├── migrations