A file upload handler shouldn’t have to worry about how the name of the file gets stored to the database, let alone where it is in the persistence lifecycle and what that means. Are we in a transaction? Is it before or after save? Can we safely raise an error?
What makes it so hard for us to design and implement a good API for our model? In my opinion it happens because we start with the data instead of behavior. For example if you’re building an online shop, how do you start the design and implementation process? In Rails you probably create migration files to create a db schema. Right?
How about reversing that process and starting with the behavior implemented in separate classes that are not coupled with the database schema? This way you will define your API at a higher level. What’s more important you will start with an API and you will add the persistence logic later.