Prehistory
I am a programmer with very little experience (I recently had about a year in labor).
About six months ago, I started working with Ruby (out of Rails) and immediately became acquainted with Active Resource and Redmine.
It was a very interesting experience, now it seems to me that Ruby is almost an ideal language (it is a language, I don’t wonder about memory consumption and speed).
However, there is a lot of magic in it, which can be difficult to understand when you read the source code of any major projects (ActiveResource I refer to them, although compared to rails, of which it is a part, this hem seems to be a drop in the ocean).
')
Problem
The project was to create a console utility (Thor-based) that works with the Redmine REST API and provides all sorts of nishtyki (by the way, inspired by the project, I am currently working on a similar utility, partially duplicating the functionality:
https://github.com/Nondv/ redmine_cli ).
If you look at the documentation for Versions or Issue Relations (
http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations ), you can pay attention to the fact that the list of relations is obtained using the address of the type
issues/<id>/relations.xml
, and for a specific object -
relations/<id>.xml
.
Actually, in order to get the list, we find a solution in the form of using
prefix
:
class Relation < ActiveResource::Base self.user = 'yet another apikey' self.password = 'we dont need password when using redmine apikey' self.site = 'www.yet-another-redmine.com'
Everything seems smart and works. But what if we need to get (or delete) a separate object?
Relation.find(id)
throws an exception
ActiveResource::MissingPrefixParam: project_id prefix_option is missing
, which is quite reasonable, we after all indicated that we should contact the address with a prefix.
Decision
Redmine REST did not provide the ability to get a separate object in the nested resources.
I personally, having worked a little more than a couple of weeks with Ruby, and having tortured Google with questions, was able to give birth to a solution, in which an anonymous class was used to obtain the list. Now I can not reproduce, but offhand something like this:
class Issue < ActiveResource::Base self.user = 'yet another apikey' self.password = 'we dont need password when using redmine apikey' self.site = 'http://www.yet-another-redmine.com'
You already smell that strange smell, right?
In general, the decision worked and in general it was made, since I could not offer alternatives.
In a personal project (link above) I got the opportunity to correct this misunderstanding (I hope, for the better). The solution is to override the
ActiveResource::Base.element_path
. For example Version:
class Version < ActiveResource::Base ... self.prefix = '/projects/:project_id/'
Conclusion
Actually, why all this? I think people who understand ActiveResource will say that this is an obvious solution.
The bottom line is that I, being only immersed in all this, ran into a problem and could not solve it, even with the help of the All-Knowing. What was my mistake? That I was afraid to understand the source code a little and did not want to study the documentation (
http://www.rubydoc.info is just a find!), In which even after looking at summary it was possible to choose something to solve the problem without involving nano-nuclear magical technology
I hope that if someone is in my position, he will not repeat my mistakes.
A week ago, I saw a statement that Larry Wall considers laziness to be one of the main advantages of a programmer. Not sure, as was written in the original Kemel-Buk (which is from there, I suppose), but in translation he used the word "virtue" rather than "dignity".
No matter how lazy I am, it does not make me a good programmer. Laziness does not always help to find a solution.
PS it seems that the post, suitable for the format of a personal mini-blog, became too fat in the process of writing.