Brick
Auto-generate models, views, controllers, and routes in a Rails app based on database structure
Install / Use
/learn @lorint/BrickREADME
Build it faster with The Brick!
Have an instantly-running Rails app from any existing database
Welcome to a seemingly-magical world of spinning up simple and yet well-rounded applications from any existing relational database! This gem auto-creates models, views, controllers, and routes, and instead of being some big pile of raw scaffolded files, they exist just in RAM. The beauty of this is that if you make database changes such as adding new tables or columns, basic functionality is immediately available without having to add any code. General behaviour around things like having lists be read-only, or when editing is enabled then rules about how to render the layout -- either inline or via a pop-up modal -- can be established. More refined behaviour and overrides for the defaults can be applied on a model-by-model basis.
|
|
|-|
You can use The Brick in several ways -- from taking a quick peek inside an existing data set, with full ability to navigate across associations -- to easily updating and creating data, exporting tables or views out to CSV or Google Sheets -- to importing sets of data, even when each row targets multiple destination tables -- to auto-creating API endpoints -- to creating a minimally-scaffolded application one file at a time -- to experimenting with various data layouts, seeing how functional a given database design will be -- and more.
A good general overview of how to start from scratch can be seen in this Youtube video by Deanin. Big thanks out to you, man!
Also available is this older video walkthrough that I had done. Probably want to pop some corn and have VOLUME UP (on the player's slider below) for this:
https://user-images.githubusercontent.com/5301131/184541537-99b37fc6-ed5e-46e9-9f99-412a03cb2cb1.mp4
Testimonials
"While migrating a python+svelte+postgres app to rails, brick was crucial for making that a possibility without having to spend a ton of time writing boiler plate models/controllers. It's been wonderful to use."
- Sean Villars
General Overview
| Version | Documentation | | -------------- | ----------------------------------------------------- | | Unreleased | https://github.com/lorint/brick/blob/master/README.md | | 1.0.242 | https://github.com/lorint/brick/blob/v1.0/README.md |
One core goal behind The Brick is to adhere as closely as possible to Rails conventions. As such, models, controllers, and views are treated independently. You can use this tool to only auto-build models if you wish, and then make your own controllers and views. Or have The Brick auto-build controllers and views for some resources as you fine-tune others with custom code. Any hybrid way you want to mix and mash that is possible. The idea is to use The Brick to automatically flesh out the more tedious and simple parts of your application, freeing up your time to focus on the more tricky bits.
The default resulting pages built out offer "index" and "show" views for each model, with references to associated models built out as links. The index page which lists all records for a given model creates just one database query in order to get records back -- no "N+1" querying problem common to other solutions which auto-scaffold related tables of data. This is due to the intelligent way in which JOINs are added to the query, even when fields are requested which are multiple "hops" away from the source table. This frees up the developer from writing many tricky ActiveRecord queries. The approach taken is that the table aliasing logic used by Arel is captured as the AST tree is being walked, and exact table correlation names are tracked in relation to the association names in the tree. This enables a really cool feature for those who work with more complex ActiveRecord queries that use JOINs -- you can find table aliases for complex ActiveRecord queries.
On the "show" page which is built out, CRUD functionality for an individual record can be performed. Date and time fields are made editable with pop-up calendars by using the very lean "flatpickr" library.
In terms of models, all major ActiveRecord associations are built out, including has_many and belongs_to, as well as has_many :through, Single Table Inheritance (STI), and polymorphic associations. Based on the foreign keys found in the database, appropriate belongs_tos are built, and corresponding has_many associations as well, being inverses of the discovered belongs_tos. From there, any tables which are found to only have belongs_to fields are considered to be "associative" (or "join") tables, and relevant has_many :through associations are then added. For example, if there are recipes and ingredients set up with an associative table like this:
Recipe --> RecipeIngredient <-- Ingredient
then first there are two belongs_to associations placed in RecipeIngredient, and then two corresponding has_manys to go the other "inverse" direction -- one in Recipe, and one in Ingredient. Finally with RecipeIngredient being recognised as an associative table (as long as it has no other columns than those two foreign keys, recipe_id and ingredient_id), then in Recipe a HMT would automatically be added:
has_many :ingredients, through: :recipe_ingredients
and in Ingredient another HMT would be added:
has_many :recipes, through: :recipe_ingredients
So when you run the whole thing you could navigate to https://localhost:3000/recipes, and see each recipe and also all the ingredients which it requires through its HMT.
If either (or both) of the foreign keys were missing in the database, they could be added into additional_references. Say that the foreign key between Recipe and RecipeIngredient is missing. It can be provided by putting a line like this in an initialiser file:
::Brick.additional_references = [['recipe_ingredients', 'recipe_id', 'recipes']]
Brick can auto-create its own initialiser file by doing rails g brick:install, and as part of
the process automatically infers missing foreign key references. These suggestions can fill in
the gaps where belongs_to and has_many associations could exist, but don't yet because of the
missing foreign key. It does this based on finding column names that look like appropriate key
names, and then makes a commented out suggestion if the data type also matches the primary key's
type. By un-commenting the ones you would like (or perhaps even all of them), then to The Brick
it will seem as if those foreign keys are present, and from there Rails will provide referential
integrity.
Myriad other settings can be found in config/initializers/brick.rb.
Some other fun generators exist as well -- if you'd like to have a set of migration files built
out from an existing database, that can be done by running the generator
bin/rails g brick:migrations. And similarly, models with bin/rails g brick:models. Even
the existing data rows themselves can be captured into a db/seeds.rb file -- just run
bin/rails g brick:seeds. More detail on this can be found below under 1.f, 1.g, and 1.h --
the various "Autogenerate ___ Files" sections.
Table of Contents
<!-- toc -->- 1. Getting Started
- 1.a. Compatibility
- 1.b. Installation
- 1.c. Displaying an ERD
- 1.d. Exposing an API
- 1.e. Full-Text Search with Opensearch or Elasticsearch
- 1.f. Autogenerate Model Files
- 1.g. Autogenerate Migration Files
- 1.h. Autogenerate Seeds File
- 1.i. Autogenerate Controller Files
- 1.j. Autogenerate Migration Files based on a Salesforce WSDL file
- 1.k. Autogenerate Migration and Seed Files based on an Existing Airtable Base
- 2. Programmatic Enhancements
- 3. More Fancy Associations
- 4. Similar Gems
- Issues
- Contributing
- Intellectual Property
1. Getting Started
1.a. Compatibility
| brick | branch | tags | ruby | activerecord | | -------------- | ---------- | ------ | -------- | ------------ | | unreleased | master | | >= 2.3.5 | >= 3.1 | | 1.0 | 1-stable | v1.x | >= 2.3.5 | >= 3.1 |
Brick will work with Rails 3.1 and onwards, and Rails 4.2.0 and above are officially supported. Rails 5.2.6, 7.1, and 7.2 are the versions which have been tested most extensively.
Compatibility with major Rails projects is very strong -- this gem can be dropped directly into a Mastodon / Canvas LMS / railsdevs / etc project and things will just WORK! Might want to set up an initializer that points things
