lorint / brick Goto Github PK
View Code? Open in Web Editor NEWAuto-generate models, views, controllers, and routes in a Rails app based on database structure
License: Other
Auto-generate models, views, controllers, and routes in a Rails app based on database structure
License: Other
Dear maintainer/creator,
I am very interested in your .select with .includes work here, as I am trying to accomplish something very similar for my company. I also saw your post in Rails forum. Did you ever consider making this a part of Rails?
Also, im trying to find how you are achieving this in this repo. I was able to grep for _brick_eager_load, but that wasnt too helpful. If you dont mind could you share a list of files Im supposed to look for to study how you accomplished this?
Sincerely,
Chuan
Given this schema in the database:
erDiagram
City {
bigint id "PK"
varchar name
}
Flight {
bigint id "PK"
bigint arrival_id " fk"
bigint departure_id " fk"
}
Airport {
bigint id "PK"
bigint city_id " fk"
varchar code
}
Airport }o--|| City : ""
Airport ||--o{ Flight : "flights_arrivals"
Airport ||--o{ Flight : "flights_departures"
Then when creating an ActiveRecord relation in order to query flights like this:
flights = Flight.joins(departure: :city, arrival: :city).left_joins(alternate_arrival: :city)
You can determine all the correlation names that Arel will build out for the ActiveRecord query like this:
flights.brick_links
=>
{""=>"flights",
"departure.city"=>"cities",
"departure"=>"airports",
"arrival.city"=>"cities_airports",
"arrival"=>"arrivals_flights",
"alternate_arrival.city"=>"cities_airports_2",
"alternate_arrival"=>"alternate_arrivals_flights"}
From a question asked out on the Rails discussion board:
/usr/local/bundle/gems/brick-1.0.131/lib/brick/frameworks/rails/engine.rb:98: warning: found `= literal' in conditional, should be ==
I have a schema generated by a visual modelling tool (DbSchema) and in generating migrations The Brick listed these errors:
Can't do devices because: premise_bt Can't do inspections because: inspector_bt, test_kit_bt, device_bt Can't do inspectors because: account_user_bt Can't do premises because: premise_manager_bt Can't do test_kits because: inspector_bt
DbSchema has a cyclic dependency checker and it came up empty—no errors.
I'm at a loss as to why The Brick failed these tables.
Are there conditions, other than cyclic dependencies, that cause failures?
Hi, mentioning that in a brand new Rails 7 application (gem "rails", "~> 7.0.4", ">= 7.0.4.2"
) w/ gem 'brick'
in the Gemfile
, I'm seeing the below when running rake db:create
(or rails db:create
). Commenting Brick and re-running doesn't produce the error. Best!
j@js-MacBook:~/Sites/git/automodels$ rake db:create --trace
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:load_config
** Execute db:create
undefined method `tr' for nil:NilClass
Did you mean? try
Couldn't create 'automodels_development' database. Please check your configuration.
rake aborted!
NoMethodError: undefined method `tr' for nil:NilClass
Did you mean? try
/Users/j/.rvm/gems/ruby-3.0.3/gems/brick-1.0.117/lib/brick/extensions.rb:2388:in `retrieve_schema_and_tables'
/Users/j/.rvm/gems/ruby-3.0.3/gems/brick-1.0.117/lib/brick/extensions.rb:2194:in `_brick_reflect_tables'
/Users/j/.rvm/gems/ruby-3.0.3/gems/brick-1.0.117/lib/brick/extensions.rb:2012:in `establish_connection'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/mysql_database_tasks.rb:8:in `establish_connection'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/mysql_database_tasks.rb:20:in `create'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:122:in `create'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:184:in `block in create_current'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:557:in `block (2 levels) in each_current_configuration'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:554:in `each'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:554:in `block in each_current_configuration'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:553:in `each'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:553:in `each_current_configuration'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/tasks/database_tasks.rb:184:in `create_current'
/Users/j/.rvm/gems/ruby-3.0.3/gems/activerecord-7.0.4.2/lib/active_record/railties/databases.rake:45:in `block (2 levels) in <main>'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:83:in `block in run'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/lib/rake/application.rb:80:in `run'
/Users/j/.rvm/gems/ruby-3.0.3/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/Users/j/.rvm/gems/ruby-3.0.3/bin/rake:25:in `load'
/Users/j/.rvm/gems/ruby-3.0.3/bin/rake:25:in `<main>'
/Users/j/.rvm/gems/ruby-3.0.3/bin/ruby_executable_hooks:22:in `eval'
/Users/j/.rvm/gems/ruby-3.0.3/bin/ruby_executable_hooks:22:in `<main>'
Tasks: TOP => db:create
Neil had a question about creating a custom kind of way to have a self-referencing JOIN. Using Brick to visualise stuff, here's a small explanation:
Trying to get all attributes in the generated ERD's, I followed the Brick.rb that was generated and tried using Brick.column_sequence = {model =>{ include: [things, and, stuff]}
but I got an "undefined method" error. After looking through the repo here I'm not seeing that anywhere, is there a new method to get columns into the diagrams?
Thanks in advance!
Since at most v1.0.176
, Rails throws an error during initialization when using The Brick. The error itself varies with version so may be caused by different issues.
[will update later this week with more details and exact versions]
Hi,
I am trying this out against my mysql db.
I am getting this error which looks like it is trying postgress not mysql (note the pg_)
/Users/eysines/.rvm/gems/ruby-3.0.0/gems/activerecord-7.0.3.1/lib/active_record/sanitization.rb:203:in `raise_if_bind_arity_mismatch': wrong number of bind variables (0 for 2) in: SELECT t.table_schema AS schema, t.table_name AS relation_name, t.table_type, (ActiveRecord::PreparedStatementInvalid)
c.column_name, c.data_type,
COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
tc.constraint_type AS const, kcu.constraint_name AS "key",
c.is_nullable
FROM INFORMATION_SCHEMA.tables AS t
LEFT OUTER JOIN INFORMATION_SCHEMA.columns AS c ON t.table_schema = c.table_schema
AND t.table_name = c.table_name
LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu ON
-- ON kcu.CONSTRAINT_CATALOG = t.table_catalog AND
kcu.CONSTRAINT_SCHEMA = c.table_schema
AND kcu.TABLE_NAME = c.table_name
AND kcu.position_in_unique_constraint IS NULL
AND kcu.ordinal_position = c.ordinal_position
LEFT OUTER JOIN INFORMATION_SCHEMA.table_constraints AS tc
ON kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
AND kcu.TABLE_NAME = tc.TABLE_NAME
AND kcu.CONSTRAINT_NAME = tc.constraint_name
WHERE t.table_schema NOT IN ('information_schema', 'pg_catalog')
AND t.table_schema = COALESCE(current_setting('SEARCH_PATH'), 'public')
-- AND t.table_type IN ('VIEW') -- 'BASE TABLE', 'FOREIGN TABLE'
AND t.table_name NOT IN ('pg_stat_statements', ?, ?)
ORDER BY 1, t.table_type DESC, c.ordinal_position
from /Users/eysines/.rvm/gems/ruby-3.0.0/gems/activerecord-7.0.3.1/lib/active_record/sanitization.rb:159:in `replace_bind_variables'
from /Users/eysines/.rvm/gems/ruby-3.0.0/gems/activerecord-7.0.3.1/lib/active_record/sanitization.rb:130:in `sanitize_sql_array'
from /Users/eysines/.rvm/gems/ruby-3.0.0/gems/brick-1.0.59/lib/brick.rb:548:in `execute_sql'
from /Users/eysines/.rvm/gems/ruby-3.0.0/gems/brick-1.0.59/lib/brick/extensions.rb:1431:in `_brick_reflect_tables'
from /Users/eysines/.rvm/gems/ruby-3.0.0/gems/brick-1.0.59/lib/brick/extensions.rb:1297:in `establish_connection'
Thanks,
Jimmy
Hi, I'm currently testing Brick and noted that on forms, a float
field has an input like:
<input type="number" name="activity[duration]" id="activity_duration">
At least on Firefox, a input type number
without a step
attribute is considered an int, and invalid with a float.
Maybe having a small step by default would do the trick (e.g.: 0.1
) ?
Hi lorint, trying to generate models I get
/usr/local/bundle/gems/brick-1.0.131/lib/generators/brick/models_generator.rb:65:in block (2 levels) in brick_models': undefined method
exists?' for Dir:Class (NoMethodError)
Dir.mkdir(dir) unless Dir.exists?(dir)
^^^^^^^^
Did you mean? exist?
from /usr/local/bundle/gems/brick-1.0.131/lib/generators/brick/models_generator.rb:63:in each' from /usr/local/bundle/gems/brick-1.0.131/lib/generators/brick/models_generator.rb:63:in
block in brick_models'
from /usr/local/bundle/gems/brick-1.0.131/lib/generators/brick/models_generator.rb:52:in each' from /usr/local/bundle/gems/brick-1.0.131/lib/generators/brick/models_generator.rb:52:in
brick_models'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor/command.rb:27:in run' from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:127:in
invoke_command'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:134:in block in invoke_all' from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:134:in
each'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:134:in map' from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:134:in
invoke_all'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor/group.rb:232:in dispatch' from /usr/local/bundle/gems/thor-1.2.1/lib/thor/base.rb:485:in
start'
from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/generators.rb:263:in invoke' from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/commands/generate/generate_command.rb:26:in
perform'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor/command.rb:27:in run' from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:127:in
invoke_command'
from /usr/local/bundle/gems/thor-1.2.1/lib/thor.rb:392:in dispatch' from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/command/base.rb:87:in
perform'
from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/command.rb:48:in invoke' from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/commands.rb:18:in
require' from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in
require'require' from bin/rails:4:in
'
I found some reference online to use File.exists instead.
Bye
Sergio
Columns whose datatype is 'citext' are converted to 't.USER-DEFINED' in the generated migrations.
Could you list all the commands/ generators we can use with Brick, I tried to generate controllers but can't figure out the command.
I tried this bin/rails g brick:controllers
but had no luck.
Hi Lorin I managed to setup a Ruby app on the Northwind db with Brick and ActiveAdmin. Everything runs fine but after I customized a little models and resources I got this strange issue. If I go to Orders in AA all is fine (see attachment#1) then if I click on the 'brick' icon I get an error (see attachment#2). I also attach a zip with models and resources.
Thank you
Sergio La Marca
admin.zip
Ruby 3.2.2
Rails 7.0.8
I created a new Rails project and connected it to a simple database containing a single table (users).
When I executed this command:
bin/rails g brick:models
this was the result:
/Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/brick-1.0.175/lib/generators/brick/models_generator.rb:32:in
block in brick_models': undefined method `split' for :db_name:Symbol (NoMethodError)
tbl_parts = tbl.split('.')
^^^^^^
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/brick-1.0.175/lib/generators/brick/models_generator.rb:31:in `map'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/brick-1.0.175/lib/generators/brick/models_generator.rb:31:in `brick_models'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/command.rb:27:in `run'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:127:in `invoke_command'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:134:in `block in invoke_all'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:134:in `each'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:134:in `map'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:134:in `invoke_all'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/group.rb:232:in `dispatch'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/base.rb:485:in `start'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.0.8/lib/rails/generators.rb:263:in `invoke'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.0.8/lib/rails/commands/generate/generate_command.rb:26:in `perform'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/command.rb:27:in `run'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:127:in `invoke_command'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor.rb:392:in `dispatch'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.0.8/lib/rails/command/base.rb:87:in `perform'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.0.8/lib/rails/command.rb:48:in `invoke'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.0.8/lib/rails/commands.rb:18:in `<main>'
from <internal:/Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
from <internal:/Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
from /Volumes/Lakshmi/Users/rob/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from bin/rails:4:in `<main>'
`
This question comes from a question raised on the Rails discussion board. Given tables created in Postgres with this code:
CREATE TABLE songs(
"songId" INTEGER,
"chartId" INTEGER,
version INTEGER,
name VARCHAR,
PRIMARY KEY ("songId", "chartId", version)
);
CREATE TABLE scores(
id SERIAL PRIMARY KEY,
"musicId" INTEGER,
level INTEGER,
version INTEGER,
instrument VARCHAR,
FOREIGN KEY ("musicId", level, version) REFERENCES songs("songId", "chartId", version)
);
INSERT INTO songs ("songId", "chartId", version, name)
VALUES (5, 3, 1, 'Requiem');
INSERT INTO songs ("songId", "chartId", version, name)
VALUES (6, 3, 1, 'Take Five');
INSERT INTO songs ("songId", "chartId", version, name)
VALUES (5, 3, 2, 'Requiem');
Your models can be created like this:
class Song < ApplicationRecord
# Primary key: songId, chartId, version
has_many :scores, query_constraints: ["musicId", "level", "version"]
end
class Score < ApplicationRecord
belongs_to :songs, query_constraints: ["musicId", "level", "version"]
end
Here is a video walkthrough showing how easy it can be using Brick to arrive upon this result:
https://github.com/lorint/brick/assets/5301131/92593ae7-75ce-4d7d-9f0a-df54ff2b0ec7
(not related is this other video about creating models for friend requests which I have linked here just as a placeholder so that Github will hold on to it.)
Hi Lorint,
Love this gem!
I'm testing this gem with a database that contains a rich_text table, and I am getting a
has_many_attached' for ActionText::RichText:Class (NoMethodError) when running the install generator.
Seems like the RichText class is not being loaded?
I'm not sure if am missing something, but I'll keep looking into it tomorrow.
ps. I'm not sure if you remember me, but I was in your Santa Monica class back in the day.
When having multiple schemas in the same db, brick will add the name of the schema to the model's name in this format <schema_name>::<table_name>. Is there a way to bypass that and generate table names without those schema names before them?
Have taken some time in version 1.0.211 to add the ability to save uploaded files to ActiveStorage. Works for both has_one_attached
and also has_many_attached
.
Here's a video demo of building an ActiveStorage project from scratch:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.