My turn to file a WTF. I’ve been meaning to fix this for a while, but never get around to it. If you do this: bin/rails g scaffold user string:name Rails will generate a scaffold for user with a column named “string” and a type of “name”.
$ cat db/migrate/20200529182157_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.name :string
t.timestamps
end
end
end
Why does the generator let me do this? We should be able to detect that “name” isn’t a valid column type and stop the generators before they make a bunch of files that are now wrong.
Happens to me all over the Rails ecosystem. Makes me think the problem is with me — that I need a language/framework that validates user input; that fails fast and clearly (not silently proceeds).
But so many people really enjoy the Ruby/Rails ecosystem as is, I think I’m not a good fit.
I think that, given that the OP is a Rails maintainer, it’s pretty safe to conclude that it has less to do with “good fit” and more to do with not enough attention being paid to keeping folks from stubbing their toes!
For me it’s just been “oops, I’ll fix Rail later”, but I run across this issue so infrequently that I forget. At an individual level, I’m sure people don’t frequently use generators, but on aggregate I’m sure this is a common issue.
One thing that’s kind of interesting is that the example of invoking the generator with the incorrect order of <column_type>:<column_name>
bin/rails g scaffold user string:name
ends up producing t.name :string in the migration file where the order is reversed (t.<column_name> :<column_type>).
Perhaps a reason people might think to run bin/rails g scaffold user string:name is that they’re thinking of <column_type>, <column_name> in the order the migration should show (t.string :name) (and they don’t realize the generator expects the opposite order).
The ordering consistencies is an interesting thing to bring up. There are several different orders that one can write depending on the notation one uses:
add_column :table, <column_name>, <column_type>
(which also is the same order when using change_column)
And is the same order as the generic t.column …:
t.column <column_name>, <column_type>
But then gets reversed in the “short-hand” version…:
Oh my god, I thought I’m only one who suffering from it. I always thought why having thor gem we have so inconsistent console tooling. Same with hidden rake -T commands. For example it doesn’t shows up rake db:migrate:reset
I suppose it would be fair to restrict generators to only known types, but keep in mind that Postgres et. al. support custom column types.
Database extensions like PostGIS/activerecord-postgis-adapter define custom column types as well, so if Rails does start enforcing known column types for migration generators, it would be nice to have a defined interface for gems to “register” new ones, similar to how ActiveRecord::Type works.