Insert generics by using Insertable<T> as Supertrait #4678
-
Hello! I've been using Diesel to implement queries for quite a few structs with a 1:1 relation to tables in my SQLite database. I've noticed that I've been duplicating a lot of code, for example inserts. This is how I've implemented them so far:
The only thing that changes for different structs is the table. So therefore my idea was to factor this function into a trait that inherits from Insertable. Here is my first version:
This would allow me to simply redefine table() for each struct implementing this trait. However, this does not compile. From my understanding, this is not possible because calling execute requires knowing the table at compile time. Can you confirm this is the case and that defining a separate insert is the correct solution? Or maybe I am doing something completely wrong? I saw on different forums that people mostly advise against implementing generics with Diesel, but something feels wrong about implementing more than 10 times the same function with so little change. Here is the link to my repo (link to the Thank you in advance for your consideration! And again, thank you for your work! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
It is kind of expected that your implementation doesn't work as it misses various trait bounds for the compiler to be able to use the That written: The other thing I advice people usually to do is to reconsider if it is even meaningful to refactor that code in such a way. With your hypothetical implementation you would be able to call your_type.insert(conn)?; (Additionally you need to implement your trait for each of your types which is another 5 lines of code.) While with the diesel provided DSL that would be your_type.insert_into(crate::schema::your_table::table).execute(conn)?; without any additional requirements beside the derive. That's just the a minimal syntactic difference, that on the other hand allow you to be much more flexible in the future by extending particular queries with returning clauses or custom inserts, etc. |
Beta Was this translation helpful? Give feedback.
It is kind of expected that your implementation doesn't work as it misses various trait bounds for the compiler to be able to use the
execute
method. I generally advice people not to write this kind of generic code and I also do not help people writing such code as they can easily and up with something they cannot maintain. So if you really want to go down that route you are on your own.That written: The other thing I advice people usually to do is to reconsider if it is even meaningful to refactor that code in such a way.
With your hypothetical implementation you would be able to call
(Additionally you need to implement your trait for each of your types which is…