Any interest in features from the "schema_plus" gem?

Hi Ronen, I'm definitely +1 for most of them. Here are some exceptions:

     t.string :column, index: { with: [:other1, :other2] } # multi-column index

I'd prefer "columns" over "with" in this case, but this is not a big issue for me. This one is a big issue in my opinion:

create_view :posts_commented_by_staff, Post.joins(comment: user).where(users: {role: 'staff'}).uniq

I don't like the idea of the migrations relying on the models and I'd prefer only the other explicit SQL-based approach to be supported in migrations.

And I didn't understand what this does:

connection.foreign_keys(table) #=> array of ForeignKeyDefinition objects

Haven't understood this part either:

AR::Base.columns.first.indexes #=> index definitions that refer to the column AR::Base.columns.first.unique? #=> whether there's a unique index.

Could you please explain it?

Also, does your gem currently support generic constraints? Or at least is there some DSL to create deferred constraints?

Good luck with getting some of those ideas approved.

Cheers, Rodrigo.

Hi Rodrigo,

Thanks for the comments.

Rodrigo Rosenfeld Rosas wrote:

Hi Ronen, I'm definitely +1 for most of them. Here are some exceptions:

    t.string :column, index: { with: [:other1, :other2] } # multi-column index

I'd prefer "columns" over "with" in this case, but this is not a big issue for me.

Not a big issue for me either. "columns" might imply that the list is all the columns rather than the additional columns? But i agree that "with" isn't great, aside from being short.

This one is a big issue in my opinion:

create_view :posts_commented_by_staff, Post.joins(comment: user).where(users: {role: 'staff'}).uniq

I don't like the idea of the migrations relying on the models and I'd prefer only the other explicit SQL-based approach to be supported in migrations.

Reasonable point. Anybody who wants to use the model-based version could do it themselves via #to_sql

    create_view :posts_commented_by_staff, Post.joins(comment: user).where(users: {role: 'staff'}).uniq.to_sql

Which is all that the current implementation does anyway: send :to_sql if the argument responds to it. So not a big deal either way in terms of coding.

And I didn't understand what this does:

connection.foreign_keys(table) #=> array of ForeignKeyDefinition objects

This looks up all the foreign key constraint that are defined on the table, and returns a list of objects containing the details of each constraint. There's also a connection.reverse_foreign_keys(table) that returns all foreign key constraints that refer to the table.

I've never actually used them in practice in an app, so they're there mostly for completeness. But of course they're used extensively within the gem.

Haven't understood this part either:

AR::Base.columns.first.indexes #=> index definitions that refer to the column AR::Base.columns.first.unique? #=> whether there's a unique index.

Could you please explain it?

Sorry that wasn't very clear. The Column object has some new methods. So if you're introspecting on the columns of a model or table, you can then query:

     column.indexes #=> array of IndexDefinition objects for all indexes that refer to the column      column.unique? #=> true if the column have a unique index on it      and a few others, see http://www.ruby-doc.org/gems/docs/s/schema_plus-1.0.1/SchemaPlus/ActiveRecord/ConnectionAdapters/Column.html

Also, does your gem currently support generic constraints? Or at least is there some DSL to create deferred constraints?

For foreign key constraints it supports

      foreign_key: { :deferrable => true }       foreign_key: { :deferrable => :initially_deferred }

It doesn't currently support other constraiints such as CHECK constraints. (just yesterday a call went out for somebody to implement it... https://twitter.com/jonleighton/status/310767523928866816 )

Good luck with getting some of those ideas approved.

Thanks!

[Hmm, sorry all. I noticed that the original post that Rodrigo responded to is gone. But there's another earlier slightly different one. To avoid confusion I'm reposting the original here, and will delete that different one. Some sort of glitch/newbie pilot error in posting to a group immediately after joining it, the post didn't show up until after I sent the second one, which I deleted because I thought it was an actual duplicate. D'oh!]

Hi Rodrigo,

Thanks for the comments.

...

And I didn't understand what this does:

connection.foreign_keys(table) #=> array of ForeignKeyDefinition objects

This looks up all the foreign key constraint that are defined on the table, and returns a list of objects containing the details of each constraint. There's also a connection.reverse_foreign_keys(table) that returns all foreign key constraints that refer to the table.

I've never actually used them in practice in an app, so they're there mostly for completeness. But of course they're used extensively within the gem.

I also don't see practical usage for this. Maybe you should keep it out of your suggestion for now and focus on the more practical public API changes. It is often easy to add new features to the API but not that simple when we want to drop them... So maybe it would be better to wait for someone to request something like that first, by provide a real use case for it.

Haven't understood this part either:

AR::Base.columns.first.indexes #=> index definitions that refer to the column AR::Base.columns.first.unique? #=> whether there's a unique index.

Could you please explain it?

Sorry that wasn't very clear. The Column object has some new methods. So if you're introspecting on the columns of a model or table, you can then query:

    column.indexes #=> array of IndexDefinition objects for all indexes that refer to the column     column.unique? #=> true if the column have a unique index on it     and a few others, see http://www.ruby-doc.org/gems/docs/s/schema_plus-1.0.1/SchemaPlus/ActiveRecord/ConnectionAdapters/Column.html

If I understand it correctly, it wouldn't be called on AR::Base but on some specific model, right? In this case I have the same feeling as the other I stated in the view. I'd rather prefer the migrations not to rely on any application models... Also, the same concerns about "foreign_keys" apply here. What would that be useful for in migrations?

Also, does your gem currently support generic constraints? Or at least is there some DSL to create deferred constraints?

For foreign key constraints it supports

     foreign_key: { :deferrable => true }      foreign_key: { :deferrable => :initially_deferred }

That's really great!

It doesn't currently support other constraiints such as CHECK constraints. (just yesterday a call went out for somebody to implement it... https://twitter.com/jonleighton/status/310767523928866816 )

The Check constraint would be another one great to support. Even though I don't currently use it in my application I can see it is pretty useful for many applications.

Specially if you want some column not only to be not-null but also not-empty for a string column.

Cheers, Rodrigo.

Rodrigo Rosenfeld Rosas wrote:

I've never actually used them in practice in an app, so they're there mostly for completeness. But of course they're used extensively within the gem.

This looks up all the foreign key constraint that are defined on the table, and returns a list of objects containing the details of each constraint. There's also a connection.reverse_foreign_keys(table) that returns all foreign key constraints that refer to the table.

I also don't see practical usage for this. Maybe you should keep it out of your suggestion for now and focus on the more practical public API changes. It is often easy to add new features to the API but not that simple when we want to drop them... So maybe it would be better to wait for someone to request something like that first, by provide a real use case for it.

Actually I do have a practical use, for apps or more likely gems that want to introspect on the foreign key constraints. For example, the "schema_associations" gem inspects the foreign key constraints in order to automatically define the corresponding associations, to keep models definitions DRY. [It's tempting to propose including schema_associations in rails core too, but I'll hold off on that ... ]

Haven't understood this part either:

AR::Base.columns.first.indexes #=> index definitions that refer to the column AR::Base.columns.first.unique? #=> whether there's a unique index.

Could you please explain it?

Sorry that wasn't very clear. The Column object has some new methods. So if you're introspecting on the columns of a model or table, you can then query:

    column.indexes #=> array of IndexDefinition objects for all indexes that refer to the column     column.unique? #=> true if the column have a unique index on it     and a few others, see http://www.ruby-doc.org/gems/docs/s/schema_plus-1.0.1/SchemaPlus/ActiveRecord/ConnectionAdapters/Column.html

If I understand it correctly, it wouldn't be called on AR::Base but on some specific model, right? In this case I have the same feeling as the other I stated in the view. I'd rather prefer the migrations not to rely on any application models... Also, the same concerns about "foreign_keys" apply here. What would that be useful for in migrations?

Sorry again not clear. This proposal doesn't add new methods to AR::Base, but rather extends the existing ActiveRecord::ConnectionAdapters::Column object that's returned by the existing AR::Base.columns method

But in any case these are not crucial, they're just conveniences. Not a big deal to leave off.

Also, does your gem currently support generic constraints? Or at least is there some DSL to create deferred constraints?

For foreign key constraints it supports

     foreign_key: { :deferrable => true }      foreign_key: { :deferrable => :initially_deferred }

That's really great!

:slight_smile:

It doesn't currently support other constraiints such as CHECK constraints. (just yesterday a call went out for somebody to implement it... https://twitter.com/jonleighton/status/310767523928866816 )

The Check constraint would be another one great to support. Even though I don't currently use it in my application I can see it is pretty useful for many applications.

Specially if you want some column not only to be not-null but also not-empty for a string column.

Yes. Also a schema_plus user is requesting support for postgres table partitioning, which requires check constraints. (but also requires supporting "CREATE TABLE ... INHERITS" so would be a bigger deal.)

Cheers, Rodrigo.

Cheers!