ActiveResource、プレフィックスおよびネストされたリソース

背景


私はほとんど経験のないプログラマーです(最近、約1年間の労働で蓄積されています)。
約6か月前、Ruby(Rails以外)で作業を開始し、すぐにActive ResourceとRedmineについて知りました。

これは非常に興味深い経験でしたが、今ではRubyはほとんど理想的な言語であるように思えます(それは言語であり、メモリ消費と速度については不思議ではありません)。

ただし、そこには多くの魔法があり、大規模なプロジェクトのソースコードを読むと理解するのが難しい場合があります(ActiveResourceを参照しますが、その一部であるレールと比較すると、このgemはバケツに落ちているようです)。

問題


プロジェクトは、Redmine REST APIで動作し、あらゆる種類のnishtyakiを提供するコンソールユーティリティ(Thorベース)を作成することでした(ところで、プロジェクトに触発され、私は現在、機能を部分的に複製する同様のユーティリティに取り組んでいます: https//github.com/Nondv/ redmine_cli )。

バージョンまたは問題の関係に関するドキュメント( http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations )を見ると、フォームのアドレスissues/<id>/relations.xmlリストを取得するために使用されていることがissues/<id>/relations.xml 、および特定のオブジェクトのrelations/<id>.xml - relations/<id>.xml

実際には、リストを取得するために、 prefixを使用するという形で解決策を見つけ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' #   ! self.prefix = '/issues/:issue_id/' end Relation.all params: { issue_id: 1 } 

すべてが豪華で機能しているようです。 しかし、別のオブジェクトを取得(または削除)する必要がある場合はどうでしょうか。
Relation.find(id)が例外ActiveResource::MissingPrefixParam: project_id prefix_option is missingスローします。これは、プレフィックスを使用してアドレスに連絡する必要があることを示しているため、非常に合理的です。

解決策


Redmine RESTは、同封のリソースで個別のオブジェクトを受け取る機会を提供しませんでした。

個人的には、ルビーで数週間以上働いて、質問でグーグルを拷問した後、リストを取得するために匿名クラスが使用されたソリューションを誕生させることができました。 今、私はそれを再現することはできませんが、このような何かを手っ取り早く:

 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' # ,    relations,       include, #         def relations tmp_class = Class.new(ActiveResource::Base) do ... self.site = "http://www.yet-another-redmine.com/issues/#{id}/" self.element_name = 'relation' end tm_class.all end end 

変な匂いがしてますよね?
一般に、決定は機能し、一般に行われました。 選択肢を提供できませんでした。

私の個人的なプロジェクト(上記のリンク)で、この誤解を修正する機会を得ました(より良いことを願っています)。 解決策は、 ActiveResource::Base.element_pathをオーバーライドするActiveResource::Base.element_pathです。 バージョンの例:

 class Version < ActiveResource::Base ... self.prefix = '/projects/:project_id/' # # ,      : # https://github.com/rails/activeresource/blob/master/lib/active_resource/base.rb#L760 #    # # Praise Open Source! # def self.element_path(id, _prefix_options = {}, query_options = nil) "/versions/#{URI.parser.escape id.to_s}#{format_extension}#{query_string(query_options)}" end end class Project < ActiveResource::Base ... def versions Version.all params: { project_id: id } end end 

おわりに


実際、なぜこれすべてなのか? ActiveResourceを理解している人は、これは明らかな解決策だと言うでしょう。

肝心なのは、このすべてに没頭しているだけで、問題にぶつかり、全知の助けを借りても解決できないということです。 私の間違いは何でしたか? 私はソースコードを少し理解することを恐れていたので、ドキュメントを勉強したくなかった( http://www.rubydoc.infoは単なる発見です!) -魔法の松葉杖テクノロジー。

誰かが私の立場にあれば、彼が私の間違いを繰り返さないことを望みます。
ほんの1週間前、私はLarry Wallが怠inessをプログラマーの主な利点の1つと考えているという声明を見ました。 キャメルブックがオリジナルでどのように書かれたかはわかりませんが(これはそこから来ていると思います)、翻訳では「尊厳」ではなく「美徳」という言葉を使用しました。

私がどれほど怠zyであっても、それは私を良いプログラマーにしないでしょう。 怠azineは常に解決策を見つけるのに役立ちません。

PS個人のミニブログの形式に適した投稿は、執筆中に太りすぎたようです。

Source: https://habr.com/ru/post/J279727/


All Articles