I find myself rarely do triggers. Not because I can't. It's just more handy to do on the ActiveRecord layer having access to all my ruby code.
Indexes, indexes on PL/pgsql procedures, foreign keys and constraints – they absolutely have their place in Rails applications.
Although you could do a rather complicated SELECT's with ActiveRecord, sometimes, for particular queries, I prefer to create a database VIEW and then point the ActiveRecord model to it.
Database views + ActiveRecord are a super power.
The rails model is an ORM (Active Record) and makes working with relational databases a breeze.
Rails migrations f^ing rule: http://guides.rubyonrails.org/active_record_migrations.html
There are two problems with that.
One is that I discovered with surprise that some developers, not only in Rails projects, don't know SQL.
The other is that you still have to synchronize those migrations with changes to the models of the framework (example: add belongs_to, has_many, etc.) even if ActiveRecord autodiscovers the fields of the tables.
The latter is true even if you write the migrations in Ruby and is true also for any pair of framework / language I know. Think about a project with microservices in many different languages and it can easily become unmanageable. "We added a foreign key from here to there, everybody update their representation of the schema." Multiply for a few times per day.
Yeah, this is the part that's the problem, not the migrations themselves. Keeping this boilerplate in sync with the db is the bane of my existence in my framework and is a completely unnecessary task. Using the ORM itself is even worse, but I digress. In apps I started from scratch, I dropped all that garbage in favor of repositories that send straight SQL to the db and all these issues dissapeared, including the slow 10x query overhead.
> The latter is true even if you write the migrations in Ruby and is true also for any pair of framework / language I know.
Maybe it's true for Rails, but there are plenty of frameworks that work fine without ORMs, ActiveRecord, or other such nonsense. To me, such systems are a step back from straight SQL and add unnecessary overhead that only gets in the way and slows down development. Having the SQL in a file and auto-generating functions on top like HugSQL does in Clojure (https://github.com/layerware/hugsql) is by far the most optimized system for db access I've seen. Other languages have these types of libraries as well. Another option is query builders. It's simply false that a db access framework needs to be configured with boilerplate based on the db schema. Yes, that's the case for the idiotic ORMs, but certainly not the case for other libraries which are available in pretty much every language.
Isn't the point of microservices to wrap the database so that other applications don't have access to it? And if you're at a stage where you're rapidly iterating on your data model, maybe start with a monolith where iteration is less costly?
What it is not is a way of mapping databases to models. The models pretty directly model the database, rather than the other way around. Quite different to something like JPA.