active_cached_resource 0.0.1.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +22 -0
  4. data/.standard.yml +2 -0
  5. data/CHANGELOG.md +5 -0
  6. data/README.md +45 -0
  7. data/Rakefile +21 -0
  8. data/example/consumer/.dockerignore +41 -0
  9. data/example/consumer/.gitattributes +9 -0
  10. data/example/consumer/.gitignore +36 -0
  11. data/example/consumer/.kamal/hooks/docker-setup.sample +3 -0
  12. data/example/consumer/.kamal/hooks/post-deploy.sample +14 -0
  13. data/example/consumer/.kamal/hooks/post-proxy-reboot.sample +3 -0
  14. data/example/consumer/.kamal/hooks/pre-build.sample +51 -0
  15. data/example/consumer/.kamal/hooks/pre-connect.sample +47 -0
  16. data/example/consumer/.kamal/hooks/pre-deploy.sample +109 -0
  17. data/example/consumer/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  18. data/example/consumer/.kamal/secrets +17 -0
  19. data/example/consumer/Dockerfile +65 -0
  20. data/example/consumer/Gemfile +17 -0
  21. data/example/consumer/Rakefile +6 -0
  22. data/example/consumer/app/controllers/application_controller.rb +2 -0
  23. data/example/consumer/app/controllers/concerns/.keep +0 -0
  24. data/example/consumer/app/jobs/application_job.rb +7 -0
  25. data/example/consumer/app/mailers/application_mailer.rb +4 -0
  26. data/example/consumer/app/models/application_record.rb +3 -0
  27. data/example/consumer/app/models/concerns/.keep +0 -0
  28. data/example/consumer/app/models/person.rb +9 -0
  29. data/example/consumer/app/views/layouts/mailer.html.erb +13 -0
  30. data/example/consumer/app/views/layouts/mailer.text.erb +1 -0
  31. data/example/consumer/bin/brakeman +7 -0
  32. data/example/consumer/bin/bundle +109 -0
  33. data/example/consumer/bin/dev +2 -0
  34. data/example/consumer/bin/docker-entrypoint +14 -0
  35. data/example/consumer/bin/jobs +6 -0
  36. data/example/consumer/bin/kamal +27 -0
  37. data/example/consumer/bin/rails +4 -0
  38. data/example/consumer/bin/rake +4 -0
  39. data/example/consumer/bin/rubocop +8 -0
  40. data/example/consumer/bin/setup +34 -0
  41. data/example/consumer/bin/thrust +5 -0
  42. data/example/consumer/config/application.rb +20 -0
  43. data/example/consumer/config/boot.rb +3 -0
  44. data/example/consumer/config/cache.yml +16 -0
  45. data/example/consumer/config/credentials.yml.enc +1 -0
  46. data/example/consumer/config/database.yml +14 -0
  47. data/example/consumer/config/deploy.yml +116 -0
  48. data/example/consumer/config/environment.rb +5 -0
  49. data/example/consumer/config/environments/development.rb +64 -0
  50. data/example/consumer/config/environments/production.rb +85 -0
  51. data/example/consumer/config/environments/test.rb +50 -0
  52. data/example/consumer/config/initializers/cors.rb +16 -0
  53. data/example/consumer/config/initializers/filter_parameter_logging.rb +8 -0
  54. data/example/consumer/config/initializers/inflections.rb +16 -0
  55. data/example/consumer/config/locales/en.yml +31 -0
  56. data/example/consumer/config/puma.rb +41 -0
  57. data/example/consumer/config/queue.yml +18 -0
  58. data/example/consumer/config/recurring.yml +10 -0
  59. data/example/consumer/config/routes.rb +10 -0
  60. data/example/consumer/config.ru +6 -0
  61. data/example/consumer/db/cache_schema.rb +14 -0
  62. data/example/consumer/db/queue_schema.rb +129 -0
  63. data/example/consumer/db/seeds.rb +0 -0
  64. data/example/consumer/lib/tasks/.keep +0 -0
  65. data/example/consumer/log/.keep +0 -0
  66. data/example/consumer/public/robots.txt +1 -0
  67. data/example/consumer/script/.keep +0 -0
  68. data/example/consumer/storage/.keep +0 -0
  69. data/example/consumer/tmp/.keep +0 -0
  70. data/example/consumer/tmp/cache/.keep +0 -0
  71. data/example/consumer/tmp/pids/.keep +0 -0
  72. data/example/consumer/tmp/storage/.keep +0 -0
  73. data/example/consumer/vendor/.keep +0 -0
  74. data/example/provider/.dockerignore +41 -0
  75. data/example/provider/.gitattributes +9 -0
  76. data/example/provider/.gitignore +32 -0
  77. data/example/provider/.kamal/hooks/docker-setup.sample +3 -0
  78. data/example/provider/.kamal/hooks/post-deploy.sample +14 -0
  79. data/example/provider/.kamal/hooks/post-proxy-reboot.sample +3 -0
  80. data/example/provider/.kamal/hooks/pre-build.sample +51 -0
  81. data/example/provider/.kamal/hooks/pre-connect.sample +47 -0
  82. data/example/provider/.kamal/hooks/pre-deploy.sample +109 -0
  83. data/example/provider/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  84. data/example/provider/.kamal/secrets +17 -0
  85. data/example/provider/Dockerfile +65 -0
  86. data/example/provider/Gemfile +14 -0
  87. data/example/provider/Rakefile +6 -0
  88. data/example/provider/app/controllers/application_controller.rb +2 -0
  89. data/example/provider/app/controllers/concerns/.keep +0 -0
  90. data/example/provider/app/controllers/people_controller.rb +68 -0
  91. data/example/provider/app/jobs/application_job.rb +7 -0
  92. data/example/provider/app/mailers/application_mailer.rb +4 -0
  93. data/example/provider/app/models/address.rb +3 -0
  94. data/example/provider/app/models/application_record.rb +3 -0
  95. data/example/provider/app/models/company.rb +3 -0
  96. data/example/provider/app/models/concerns/.keep +0 -0
  97. data/example/provider/app/models/person.rb +6 -0
  98. data/example/provider/app/views/layouts/mailer.html.erb +13 -0
  99. data/example/provider/app/views/layouts/mailer.text.erb +1 -0
  100. data/example/provider/bin/brakeman +7 -0
  101. data/example/provider/bin/bundle +109 -0
  102. data/example/provider/bin/dev +2 -0
  103. data/example/provider/bin/docker-entrypoint +14 -0
  104. data/example/provider/bin/jobs +6 -0
  105. data/example/provider/bin/kamal +27 -0
  106. data/example/provider/bin/rails +4 -0
  107. data/example/provider/bin/rake +4 -0
  108. data/example/provider/bin/rubocop +8 -0
  109. data/example/provider/bin/setup +34 -0
  110. data/example/provider/bin/thrust +5 -0
  111. data/example/provider/config/application.rb +44 -0
  112. data/example/provider/config/boot.rb +3 -0
  113. data/example/provider/config/cache.yml +16 -0
  114. data/example/provider/config/credentials.yml.enc +1 -0
  115. data/example/provider/config/database.yml +20 -0
  116. data/example/provider/config/deploy.yml +116 -0
  117. data/example/provider/config/environment.rb +5 -0
  118. data/example/provider/config/environments/development.rb +64 -0
  119. data/example/provider/config/environments/production.rb +85 -0
  120. data/example/provider/config/environments/test.rb +50 -0
  121. data/example/provider/config/initializers/cors.rb +16 -0
  122. data/example/provider/config/initializers/filter_parameter_logging.rb +8 -0
  123. data/example/provider/config/initializers/inflections.rb +16 -0
  124. data/example/provider/config/locales/en.yml +31 -0
  125. data/example/provider/config/puma.rb +41 -0
  126. data/example/provider/config/queue.yml +18 -0
  127. data/example/provider/config/recurring.yml +10 -0
  128. data/example/provider/config/routes.rb +4 -0
  129. data/example/provider/config.ru +6 -0
  130. data/example/provider/db/cache_schema.rb +14 -0
  131. data/example/provider/db/migrate/20241202183937_create_people.rb +11 -0
  132. data/example/provider/db/migrate/20241202183955_create_addresses.rb +13 -0
  133. data/example/provider/db/migrate/20241202184017_create_companies.rb +14 -0
  134. data/example/provider/db/queue_schema.rb +129 -0
  135. data/example/provider/db/schema.rb +47 -0
  136. data/example/provider/db/seeds.rb +18 -0
  137. data/example/provider/lib/tasks/.keep +0 -0
  138. data/example/provider/log/.keep +0 -0
  139. data/example/provider/public/robots.txt +1 -0
  140. data/example/provider/script/.keep +0 -0
  141. data/example/provider/storage/.keep +0 -0
  142. data/example/provider/tmp/.keep +0 -0
  143. data/example/provider/tmp/pids/.keep +0 -0
  144. data/example/provider/tmp/storage/.keep +0 -0
  145. data/example/provider/vendor/.keep +0 -0
  146. data/lib/active_cached_resource/caching.rb +176 -0
  147. data/lib/active_cached_resource/caching_strategies/active_support_cache.rb +31 -0
  148. data/lib/active_cached_resource/caching_strategies/base.rb +114 -0
  149. data/lib/active_cached_resource/caching_strategies/sql_cache.rb +32 -0
  150. data/lib/active_cached_resource/configuration.rb +50 -0
  151. data/lib/active_cached_resource/logger.rb +22 -0
  152. data/lib/active_cached_resource/model.rb +33 -0
  153. data/lib/active_cached_resource/version.rb +12 -0
  154. data/lib/active_cached_resource.rb +64 -0
  155. data/lib/activeresource/.gitignore +15 -0
  156. data/lib/activeresource/README.md +283 -0
  157. data/lib/activeresource/examples/performance.rb +72 -0
  158. data/lib/activeresource/lib/active_resource/active_job_serializer.rb +26 -0
  159. data/lib/activeresource/lib/active_resource/associations/builder/association.rb +32 -0
  160. data/lib/activeresource/lib/active_resource/associations/builder/belongs_to.rb +16 -0
  161. data/lib/activeresource/lib/active_resource/associations/builder/has_many.rb +14 -0
  162. data/lib/activeresource/lib/active_resource/associations/builder/has_one.rb +14 -0
  163. data/lib/activeresource/lib/active_resource/associations.rb +175 -0
  164. data/lib/activeresource/lib/active_resource/base.rb +1741 -0
  165. data/lib/activeresource/lib/active_resource/callbacks.rb +22 -0
  166. data/lib/activeresource/lib/active_resource/collection.rb +214 -0
  167. data/lib/activeresource/lib/active_resource/connection.rb +298 -0
  168. data/lib/activeresource/lib/active_resource/custom_methods.rb +129 -0
  169. data/lib/activeresource/lib/active_resource/exceptions.rb +98 -0
  170. data/lib/activeresource/lib/active_resource/formats/json_format.rb +28 -0
  171. data/lib/activeresource/lib/active_resource/formats/xml_format.rb +27 -0
  172. data/lib/activeresource/lib/active_resource/formats.rb +24 -0
  173. data/lib/activeresource/lib/active_resource/http_mock.rb +386 -0
  174. data/lib/activeresource/lib/active_resource/inheriting_hash.rb +34 -0
  175. data/lib/activeresource/lib/active_resource/log_subscriber.rb +26 -0
  176. data/lib/activeresource/lib/active_resource/railtie.rb +31 -0
  177. data/lib/activeresource/lib/active_resource/reflection.rb +78 -0
  178. data/lib/activeresource/lib/active_resource/schema.rb +60 -0
  179. data/lib/activeresource/lib/active_resource/singleton.rb +111 -0
  180. data/lib/activeresource/lib/active_resource/threadsafe_attributes.rb +65 -0
  181. data/lib/activeresource/lib/active_resource/validations.rb +176 -0
  182. data/lib/activeresource/lib/active_resource.rb +49 -0
  183. data/lib/activeresource/lib/activeresource.rb +3 -0
  184. data/lib/activeresource/test/abstract_unit.rb +153 -0
  185. data/lib/activeresource/test/cases/active_job_serializer_test.rb +53 -0
  186. data/lib/activeresource/test/cases/association_test.rb +104 -0
  187. data/lib/activeresource/test/cases/associations/builder/belongs_to_test.rb +42 -0
  188. data/lib/activeresource/test/cases/associations/builder/has_many_test.rb +28 -0
  189. data/lib/activeresource/test/cases/associations/builder/has_one_test.rb +28 -0
  190. data/lib/activeresource/test/cases/authorization_test.rb +276 -0
  191. data/lib/activeresource/test/cases/base/custom_methods_test.rb +155 -0
  192. data/lib/activeresource/test/cases/base/equality_test.rb +53 -0
  193. data/lib/activeresource/test/cases/base/load_test.rb +249 -0
  194. data/lib/activeresource/test/cases/base/schema_test.rb +428 -0
  195. data/lib/activeresource/test/cases/base_errors_test.rb +129 -0
  196. data/lib/activeresource/test/cases/base_test.rb +1622 -0
  197. data/lib/activeresource/test/cases/callbacks_test.rb +155 -0
  198. data/lib/activeresource/test/cases/collection_test.rb +172 -0
  199. data/lib/activeresource/test/cases/connection_test.rb +357 -0
  200. data/lib/activeresource/test/cases/finder_test.rb +217 -0
  201. data/lib/activeresource/test/cases/format_test.rb +137 -0
  202. data/lib/activeresource/test/cases/http_mock_test.rb +213 -0
  203. data/lib/activeresource/test/cases/inheritence_test.rb +19 -0
  204. data/lib/activeresource/test/cases/inheriting_hash_test.rb +25 -0
  205. data/lib/activeresource/test/cases/log_subscriber_test.rb +63 -0
  206. data/lib/activeresource/test/cases/reflection_test.rb +65 -0
  207. data/lib/activeresource/test/cases/validations_test.rb +78 -0
  208. data/lib/activeresource/test/fixtures/address.rb +20 -0
  209. data/lib/activeresource/test/fixtures/beast.rb +16 -0
  210. data/lib/activeresource/test/fixtures/comment.rb +5 -0
  211. data/lib/activeresource/test/fixtures/customer.rb +5 -0
  212. data/lib/activeresource/test/fixtures/inventory.rb +14 -0
  213. data/lib/activeresource/test/fixtures/person.rb +15 -0
  214. data/lib/activeresource/test/fixtures/pet.rb +6 -0
  215. data/lib/activeresource/test/fixtures/post.rb +5 -0
  216. data/lib/activeresource/test/fixtures/product.rb +11 -0
  217. data/lib/activeresource/test/fixtures/project.rb +19 -0
  218. data/lib/activeresource/test/fixtures/proxy.rb +6 -0
  219. data/lib/activeresource/test/fixtures/sound.rb +11 -0
  220. data/lib/activeresource/test/fixtures/street_address.rb +6 -0
  221. data/lib/activeresource/test/fixtures/subscription_plan.rb +7 -0
  222. data/lib/activeresource/test/fixtures/weather.rb +21 -0
  223. data/lib/activeresource/test/setter_trap.rb +28 -0
  224. data/lib/activeresource/test/singleton_test.rb +138 -0
  225. data/lib/activeresource/test/threadsafe_attributes_test.rb +91 -0
  226. data/lib/generators/active_cached_resource/install_generator.rb +31 -0
  227. data/lib/generators/active_cached_resource/templates/migration.erb +16 -0
  228. data/sorbet/config +4 -0
  229. data/sorbet/rbi/annotations/.gitattributes +1 -0
  230. data/sorbet/rbi/annotations/activemodel.rbi +89 -0
  231. data/sorbet/rbi/annotations/activesupport.rbi +457 -0
  232. data/sorbet/rbi/annotations/minitest.rbi +119 -0
  233. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  234. data/sorbet/rbi/dsl/.gitattributes +1 -0
  235. data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
  236. data/sorbet/rbi/gems/.gitattributes +1 -0
  237. data/sorbet/rbi/gems/actioncable@8.0.0.rbi +252 -0
  238. data/sorbet/rbi/gems/actionmailbox@8.0.0.rbi +9 -0
  239. data/sorbet/rbi/gems/actionmailer@8.0.0.rbi +9 -0
  240. data/sorbet/rbi/gems/actionpack@8.0.0.rbi +20909 -0
  241. data/sorbet/rbi/gems/actiontext@8.0.0.rbi +9 -0
  242. data/sorbet/rbi/gems/actionview@8.0.0.rbi +16207 -0
  243. data/sorbet/rbi/gems/activejob@8.0.0.rbi +9 -0
  244. data/sorbet/rbi/gems/activemodel-serializers-xml@1.0.3.rbi +166 -0
  245. data/sorbet/rbi/gems/activemodel@8.0.0.rbi +6857 -0
  246. data/sorbet/rbi/gems/activerecord@8.0.0.rbi +42896 -0
  247. data/sorbet/rbi/gems/activeresource@6.1.4.rbi +3944 -0
  248. data/sorbet/rbi/gems/activestorage@8.0.0.rbi +9 -0
  249. data/sorbet/rbi/gems/activesupport@8.0.0.rbi +21251 -0
  250. data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
  251. data/sorbet/rbi/gems/base64@0.2.0.rbi +509 -0
  252. data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
  253. data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +78 -0
  254. data/sorbet/rbi/gems/builder@3.3.0.rbi +9 -0
  255. data/sorbet/rbi/gems/bump@0.10.0.rbi +169 -0
  256. data/sorbet/rbi/gems/byebug@11.1.3.rbi +3607 -0
  257. data/sorbet/rbi/gems/coderay@1.1.3.rbi +3427 -0
  258. data/sorbet/rbi/gems/concurrent-ruby@1.3.4.rbi +11645 -0
  259. data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +9 -0
  260. data/sorbet/rbi/gems/crass@1.0.6.rbi +623 -0
  261. data/sorbet/rbi/gems/date@3.4.0.rbi +75 -0
  262. data/sorbet/rbi/gems/diff-lcs@1.5.1.rbi +1131 -0
  263. data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
  264. data/sorbet/rbi/gems/drb@2.2.1.rbi +1347 -0
  265. data/sorbet/rbi/gems/erubi@1.13.0.rbi +150 -0
  266. data/sorbet/rbi/gems/globalid@1.2.1.rbi +9 -0
  267. data/sorbet/rbi/gems/i18n@1.14.6.rbi +2359 -0
  268. data/sorbet/rbi/gems/io-console@0.7.2.rbi +9 -0
  269. data/sorbet/rbi/gems/json@2.8.2.rbi +1901 -0
  270. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14238 -0
  271. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  272. data/sorbet/rbi/gems/logger@1.6.1.rbi +920 -0
  273. data/sorbet/rbi/gems/loofah@2.23.1.rbi +1081 -0
  274. data/sorbet/rbi/gems/mail@2.8.1.rbi +9 -0
  275. data/sorbet/rbi/gems/marcel@1.0.4.rbi +9 -0
  276. data/sorbet/rbi/gems/method_source@1.1.0.rbi +304 -0
  277. data/sorbet/rbi/gems/mini_mime@1.1.5.rbi +9 -0
  278. data/sorbet/rbi/gems/minitest@5.25.2.rbi +1547 -0
  279. data/sorbet/rbi/gems/net-imap@0.5.1.rbi +9 -0
  280. data/sorbet/rbi/gems/net-pop@0.1.2.rbi +9 -0
  281. data/sorbet/rbi/gems/net-protocol@0.2.2.rbi +292 -0
  282. data/sorbet/rbi/gems/net-smtp@0.5.0.rbi +9 -0
  283. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  284. data/sorbet/rbi/gems/nio4r@2.7.4.rbi +9 -0
  285. data/sorbet/rbi/gems/nokogiri@1.16.7.rbi +7311 -0
  286. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  287. data/sorbet/rbi/gems/parser@3.3.6.0.rbi +5519 -0
  288. data/sorbet/rbi/gems/prism@1.2.0.rbi +39085 -0
  289. data/sorbet/rbi/gems/pry-byebug@3.10.1.rbi +1151 -0
  290. data/sorbet/rbi/gems/pry@0.14.2.rbi +10076 -0
  291. data/sorbet/rbi/gems/psych@5.2.0.rbi +1785 -0
  292. data/sorbet/rbi/gems/racc@1.8.1.rbi +162 -0
  293. data/sorbet/rbi/gems/rack-session@2.0.0.rbi +727 -0
  294. data/sorbet/rbi/gems/rack-test@2.1.0.rbi +747 -0
  295. data/sorbet/rbi/gems/rack@3.1.8.rbi +4905 -0
  296. data/sorbet/rbi/gems/rackup@2.2.1.rbi +230 -0
  297. data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +758 -0
  298. data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +785 -0
  299. data/sorbet/rbi/gems/rails@8.0.0.rbi +9 -0
  300. data/sorbet/rbi/gems/railties@8.0.0.rbi +6287 -0
  301. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
  302. data/sorbet/rbi/gems/rake@13.2.1.rbi +3091 -0
  303. data/sorbet/rbi/gems/rbi@0.2.1.rbi +4535 -0
  304. data/sorbet/rbi/gems/rdoc@6.8.1.rbi +12572 -0
  305. data/sorbet/rbi/gems/regexp_parser@2.9.2.rbi +3772 -0
  306. data/sorbet/rbi/gems/reline@0.5.12.rbi +2416 -0
  307. data/sorbet/rbi/gems/rexml@3.3.9.rbi +4858 -0
  308. data/sorbet/rbi/gems/rspec-core@3.13.2.rbi +11287 -0
  309. data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
  310. data/sorbet/rbi/gems/rspec-mocks@3.13.2.rbi +5341 -0
  311. data/sorbet/rbi/gems/rspec-support@3.13.1.rbi +1630 -0
  312. data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
  313. data/sorbet/rbi/gems/rubocop-ast@1.36.1.rbi +7303 -0
  314. data/sorbet/rbi/gems/rubocop-performance@1.21.1.rbi +9 -0
  315. data/sorbet/rbi/gems/rubocop@1.65.1.rbi +58170 -0
  316. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  317. data/sorbet/rbi/gems/securerandom@0.3.2.rbi +395 -0
  318. data/sorbet/rbi/gems/simplecov-html@0.13.1.rbi +225 -0
  319. data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2149 -0
  320. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
  321. data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
  322. data/sorbet/rbi/gems/standard-custom@1.0.2.rbi +9 -0
  323. data/sorbet/rbi/gems/standard-performance@1.4.0.rbi +9 -0
  324. data/sorbet/rbi/gems/standard@1.40.0.rbi +929 -0
  325. data/sorbet/rbi/gems/stringio@3.1.2.rbi +9 -0
  326. data/sorbet/rbi/gems/tapioca@0.16.4.rbi +3597 -0
  327. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  328. data/sorbet/rbi/gems/timeout@0.4.2.rbi +151 -0
  329. data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
  330. data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
  331. data/sorbet/rbi/gems/uri@1.0.2.rbi +2377 -0
  332. data/sorbet/rbi/gems/useragent@0.16.10.rbi +9 -0
  333. data/sorbet/rbi/gems/websocket-driver@0.7.6.rbi +9 -0
  334. data/sorbet/rbi/gems/websocket-extensions@0.1.5.rbi +9 -0
  335. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  336. data/sorbet/rbi/gems/yard@0.9.37.rbi +18504 -0
  337. data/sorbet/rbi/gems/zeitwerk@2.7.1.rbi +9 -0
  338. data/sorbet/tapioca/config.yml +13 -0
  339. data/sorbet/tapioca/require.rb +12 -0
  340. metadata +543 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
4
+
5
+ module ActiveResource
6
+ module Callbacks
7
+ extend ActiveSupport::Concern
8
+
9
+ CALLBACKS = [
10
+ :before_validation, :after_validation, :before_save, :around_save, :after_save,
11
+ :before_create, :around_create, :after_create, :before_update, :around_update,
12
+ :after_update, :before_destroy, :around_destroy, :after_destroy
13
+ ]
14
+
15
+ included do
16
+ extend ActiveModel::Callbacks
17
+ include ActiveModel::Validations::Callbacks
18
+
19
+ define_model_callbacks :save, :create, :update, :destroy
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,214 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+ require "active_support/inflector"
5
+
6
+ module ActiveResource # :nodoc:
7
+ class Collection # :nodoc:
8
+ include Enumerable
9
+ delegate :to_yaml, *Array.public_instance_methods(false), to: :request_resources!
10
+
11
+ attr_accessor :resource_class, :query_params, :path_params
12
+ attr_writer :prefix_options
13
+ attr_reader :from
14
+
15
+ # ActiveResource::Collection is a wrapper to handle parsing index responses that
16
+ # do not directly map to Rails conventions.
17
+ #
18
+ # You can define a custom class that inherits from ActiveResource::Collection
19
+ # in order to to set the elements instance.
20
+ #
21
+ # GET /posts.json delivers following response body:
22
+ # {
23
+ # posts: [
24
+ # {
25
+ # title: "ActiveResource now has associations",
26
+ # body: "Lorem Ipsum"
27
+ # },
28
+ # {...}
29
+ # ],
30
+ # next_page: "/posts.json?page=2"
31
+ # }
32
+ #
33
+ # A Post class can be setup to handle it with:
34
+ #
35
+ # class Post < ActiveResource::Base
36
+ # self.site = "http://example.com"
37
+ # self.collection_parser = PostCollection
38
+ # end
39
+ #
40
+ # And the collection parser:
41
+ #
42
+ # class PostCollection < ActiveResource::Collection
43
+ # attr_accessor :next_page
44
+ # def parse_response(parsed = {})
45
+ # @elements = parsed['posts']
46
+ # @next_page = parsed['next_page']
47
+ # end
48
+ # end
49
+ #
50
+ # The result from a find method that returns multiple entries will now be a
51
+ # PostParser instance. ActiveResource::Collection includes Enumerable and
52
+ # instances can be iterated over just like an array.
53
+ # @posts = Post.find(:all) # => PostCollection:xxx
54
+ # @posts.next_page # => "/posts.json?page=2"
55
+ # @posts.map(&:id) # =>[1, 3, 5 ...]
56
+ #
57
+ # The ActiveResource::Collection#parse_response method will receive the ActiveResource::Formats parsed result
58
+ # and should set @elements.
59
+ def initialize(elements = [], from = nil)
60
+ @from = from
61
+ @elements = elements
62
+ @requested = false
63
+ # This can get called without a response, so parse only if response is present
64
+ parse_response(@elements) if @elements.present?
65
+ end
66
+
67
+ # Processes and sets the collection elements. This method assigns the provided `elements`
68
+ # (or an empty array if none provided) to the `@elements` instance variable.
69
+ #
70
+ # ==== Arguments
71
+ #
72
+ # +elements+ (Array<Object>) - An optional array of resources to be set as the collection elements.
73
+ # Defaults to an empty array.
74
+ #
75
+ # This method is called after fetching the resource and can be overridden by subclasses to
76
+ # handle any specific response format of the API.
77
+ def parse_response(elements)
78
+ @elements = elements || []
79
+ end
80
+
81
+ # Returns the prefix options for the collection, which are used for constructing the resource path.
82
+ #
83
+ # ==== Returns
84
+ #
85
+ # [Hash] The prefix options for the collection.
86
+ def prefix_options
87
+ @prefix_options || {}
88
+ end
89
+
90
+ # Refreshes the collection by re-fetching the resources from the API.
91
+ #
92
+ # ==== Returns
93
+ #
94
+ # [Array<Object>] The collection of resources retrieved from the API.
95
+ def refresh
96
+ @requested = false
97
+ request_resources!
98
+ end
99
+
100
+ # Executes the request to fetch the collection of resources from the API and returns the collection.
101
+ #
102
+ # ==== Returns
103
+ #
104
+ # [ActiveResource::Collection] The collection of resources.
105
+ def call
106
+ request_resources!
107
+ self
108
+ end
109
+
110
+ # Checks if the collection has been requested.
111
+ #
112
+ # ==== Returns
113
+ #
114
+ # [Boolean] true if the collection has been requested, false otherwise.
115
+ def requested?
116
+ @requested
117
+ end
118
+
119
+ # Returns the first resource in the collection, or creates a new resource using the provided
120
+ # attributes if the collection is empty.
121
+ #
122
+ # ==== Arguments
123
+ #
124
+ # +attributes+ (Hash) - The attributes for creating the resource.
125
+ #
126
+ # ==== Returns
127
+ #
128
+ # [Object] The first resource, or a newly created resource if none exist.
129
+ #
130
+ # ==== Example
131
+ # post = PostCollection.where(title: "New Post").first_or_create
132
+ # # => Post instance with title "New Post"
133
+ def first_or_create(attributes = {})
134
+ first || resource_class.create(query_params.update(attributes))
135
+ rescue NoMethodError
136
+ raise "Cannot create resource from resource type: #{resource_class.inspect}"
137
+ end
138
+
139
+ # Returns the first resource in the collection, or initializes a new resource using the provided
140
+ # attributes if the collection is empty.
141
+ #
142
+ # ==== Arguments
143
+ #
144
+ # +attributes+ (Hash) - The attributes for initializing the resource.
145
+ #
146
+ # ==== Returns
147
+ #
148
+ # [Object] The first resource, or a newly initialized resource if none exist.
149
+ #
150
+ # ==== Example
151
+ # post = PostCollection.where(title: "New Post").first_or_initialize
152
+ # # => Post instance with title "New Post"
153
+ def first_or_initialize(attributes = {})
154
+ first || resource_class.new(query_params.update(attributes))
155
+ rescue NoMethodError
156
+ raise "Cannot build resource from resource type: #{resource_class.inspect}"
157
+ end
158
+
159
+ # Filters the collection based on the provided clauses (query parameters).
160
+ #
161
+ # ==== Arguments
162
+ #
163
+ # +clauses+ (Hash) - A hash of query parameters used to filter the collection.
164
+ #
165
+ # ==== Returns
166
+ #
167
+ # [ActiveResource::Collection] A new collection filtered by the specified clauses.
168
+ #
169
+ # ==== Example
170
+ # filtered_posts = PostCollection.where(title: "Post 1")
171
+ # # => PostCollection:xxx (filtered collection)
172
+ def where(clauses = {})
173
+ raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
174
+ new_clauses = query_params.merge(clauses)
175
+ resource_class.where(new_clauses)
176
+ end
177
+
178
+ private
179
+ def query_string(options)
180
+ "?#{options.to_query}" unless options.nil? || options.empty?
181
+ end
182
+
183
+ # Requests resources from the API and parses the response. The resources are then mapped to their respective
184
+ # resource class instances.
185
+ #
186
+ # ==== Returns
187
+ #
188
+ # [Array<Object>] The collection of resources retrieved from the API.
189
+ def request_resources!
190
+ return @elements if requested?
191
+ response =
192
+ case from
193
+ when Symbol
194
+ resource_class.get(from, path_params)
195
+ when String
196
+ path = "#{from}#{query_string(query_params)}"
197
+ resource_class.format.decode(resource_class.connection.get(path, resource_class.headers).body)
198
+ else
199
+ path = resource_class.collection_path(prefix_options, query_params)
200
+ resource_class.format.decode(resource_class.connection.get(path, resource_class.headers).body)
201
+ end
202
+
203
+ # Update the elements
204
+ parse_response(response)
205
+ @elements.map! { |e| resource_class.instantiate_record(e, prefix_options) }
206
+ rescue ActiveResource::ResourceNotFound
207
+ # Swallowing ResourceNotFound exceptions and return nothing - as per ActiveRecord.
208
+ # Needs to be empty array as Array methods are delegated
209
+ []
210
+ ensure
211
+ @requested = true
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/benchmark"
4
+ require "active_support/core_ext/object/inclusion"
5
+ require "net/https"
6
+ require "date"
7
+ require "time"
8
+
9
+ module ActiveResource
10
+ # Class to handle connections to remote web services.
11
+ # This class is used by ActiveResource::Base to interface with REST
12
+ # services.
13
+ class Connection
14
+ HTTP_FORMAT_HEADER_NAMES = { get: "Accept",
15
+ put: "Content-Type",
16
+ post: "Content-Type",
17
+ patch: "Content-Type",
18
+ delete: "Accept",
19
+ head: "Accept"
20
+ }
21
+
22
+ attr_reader :site, :user, :password, :bearer_token, :auth_type, :timeout, :open_timeout, :read_timeout, :proxy, :ssl_options
23
+ attr_accessor :format, :logger
24
+
25
+ class << self
26
+ def requests
27
+ @@requests ||= []
28
+ end
29
+ end
30
+
31
+ # The +site+ parameter is required and will set the +site+
32
+ # attribute to the URI for the remote resource service.
33
+ def initialize(site, format = ActiveResource::Formats::JsonFormat, logger: nil)
34
+ raise ArgumentError, "Missing site URI" unless site
35
+ @proxy = @user = @password = @bearer_token = nil
36
+ self.site = site
37
+ self.format = format
38
+ self.logger = logger
39
+ end
40
+
41
+ # Set URI for remote service.
42
+ def site=(site)
43
+ @site = site.is_a?(URI) ? site : URI.parse(site)
44
+ @ssl_options ||= {} if @site.is_a?(URI::HTTPS)
45
+ @user = URI_PARSER.unescape(@site.user) if @site.user
46
+ @password = URI_PARSER.unescape(@site.password) if @site.password
47
+ end
48
+
49
+ # Set the proxy for remote service.
50
+ def proxy=(proxy)
51
+ @proxy = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
52
+ end
53
+
54
+ # Sets the user for remote service.
55
+ attr_writer :user
56
+
57
+ # Sets the password for remote service.
58
+ attr_writer :password
59
+
60
+ # Sets the bearer token for remote service.
61
+ attr_writer :bearer_token
62
+
63
+ # Sets the auth type for remote service.
64
+ def auth_type=(auth_type)
65
+ @auth_type = legitimize_auth_type(auth_type)
66
+ end
67
+
68
+ # Sets the number of seconds after which HTTP requests to the remote service should time out.
69
+ attr_writer :timeout
70
+
71
+ # Sets the number of seconds after which HTTP connects to the remote service should time out.
72
+ attr_writer :open_timeout
73
+
74
+ # Sets the number of seconds after which HTTP read requests to the remote service should time out.
75
+ attr_writer :read_timeout
76
+
77
+ # Hash of options applied to Net::HTTP instance when +site+ protocol is 'https'.
78
+ attr_writer :ssl_options
79
+
80
+ # Executes a GET request.
81
+ # Used to get (find) resources.
82
+ def get(path, headers = {})
83
+ with_auth { request(:get, path, build_request_headers(headers, :get, self.site.merge(path))) }
84
+ end
85
+
86
+ # Executes a DELETE request (see HTTP protocol documentation if unfamiliar).
87
+ # Used to delete resources.
88
+ def delete(path, headers = {})
89
+ with_auth { request(:delete, path, build_request_headers(headers, :delete, self.site.merge(path))) }
90
+ end
91
+
92
+ # Executes a PATCH request (see HTTP protocol documentation if unfamiliar).
93
+ # Used to update resources.
94
+ def patch(path, body = "", headers = {})
95
+ with_auth { request(:patch, path, body.to_s, build_request_headers(headers, :patch, self.site.merge(path))) }
96
+ end
97
+
98
+ # Executes a PUT request (see HTTP protocol documentation if unfamiliar).
99
+ # Used to update resources.
100
+ def put(path, body = "", headers = {})
101
+ with_auth { request(:put, path, body.to_s, build_request_headers(headers, :put, self.site.merge(path))) }
102
+ end
103
+
104
+ # Executes a POST request.
105
+ # Used to create new resources.
106
+ def post(path, body = "", headers = {})
107
+ with_auth { request(:post, path, body.to_s, build_request_headers(headers, :post, self.site.merge(path))) }
108
+ end
109
+
110
+ # Executes a HEAD request.
111
+ # Used to obtain meta-information about resources, such as whether they exist and their size (via response headers).
112
+ def head(path, headers = {})
113
+ with_auth { request(:head, path, build_request_headers(headers, :head, self.site.merge(path))) }
114
+ end
115
+
116
+ private
117
+ # Makes a request to the remote service.
118
+ def request(method, path, *arguments)
119
+ result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
120
+ payload[:method] = method
121
+ payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
122
+ payload[:result] = http.send(method, path, *arguments)
123
+ end
124
+ handle_response(result)
125
+ rescue Timeout::Error => e
126
+ raise TimeoutError.new(e.message)
127
+ rescue OpenSSL::SSL::SSLError => e
128
+ raise SSLError.new(e.message)
129
+ end
130
+
131
+ # Handles response and error codes from the remote service.
132
+ def handle_response(response)
133
+ case response.code.to_i
134
+ when 301, 302, 303, 307
135
+ raise(Redirection.new(response))
136
+ when 200...400
137
+ response
138
+ when 400
139
+ raise(BadRequest.new(response))
140
+ when 401
141
+ raise(UnauthorizedAccess.new(response))
142
+ when 402
143
+ raise(PaymentRequired.new(response))
144
+ when 403
145
+ raise(ForbiddenAccess.new(response))
146
+ when 404
147
+ raise(ResourceNotFound.new(response))
148
+ when 405
149
+ raise(MethodNotAllowed.new(response))
150
+ when 409
151
+ raise(ResourceConflict.new(response))
152
+ when 410
153
+ raise(ResourceGone.new(response))
154
+ when 412
155
+ raise(PreconditionFailed.new(response))
156
+ when 422
157
+ raise(ResourceInvalid.new(response))
158
+ when 429
159
+ raise(TooManyRequests.new(response))
160
+ when 401...500
161
+ raise(ClientError.new(response))
162
+ when 500...600
163
+ raise(ServerError.new(response))
164
+ else
165
+ raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
166
+ end
167
+ end
168
+
169
+ # Creates new Net::HTTP instance for communication with the
170
+ # remote service and resources.
171
+ def http
172
+ configure_http(new_http)
173
+ end
174
+
175
+ def new_http
176
+ if @proxy
177
+ user = URI_PARSER.unescape(@proxy.user) if @proxy.user
178
+ password = URI_PARSER.unescape(@proxy.password) if @proxy.password
179
+ Net::HTTP.new(@site.host, @site.port, @proxy.host, @proxy.port, user, password)
180
+ else
181
+ Net::HTTP.new(@site.host, @site.port)
182
+ end
183
+ end
184
+
185
+ def configure_http(http)
186
+ apply_ssl_options(http).tap do |https|
187
+ # Net::HTTP timeouts default to 60 seconds.
188
+ if defined? @timeout
189
+ https.open_timeout = @timeout
190
+ https.read_timeout = @timeout
191
+ end
192
+ https.open_timeout = @open_timeout if defined?(@open_timeout)
193
+ https.read_timeout = @read_timeout if defined?(@read_timeout)
194
+ end
195
+ end
196
+
197
+ def apply_ssl_options(http)
198
+ http.tap do |https|
199
+ # Skip config if site is already a https:// URI.
200
+ if defined? @ssl_options
201
+ http.use_ssl = true
202
+
203
+ # All the SSL options have corresponding http settings.
204
+ @ssl_options.each { |key, value| http.send "#{key}=", value }
205
+ end
206
+ end
207
+ end
208
+
209
+ def default_header
210
+ @default_header ||= {}
211
+ end
212
+
213
+ # Builds headers for request to remote service.
214
+ def build_request_headers(headers, http_method, uri)
215
+ authorization_header(http_method, uri).update(default_header).update(http_format_header(http_method)).update(headers.to_hash)
216
+ end
217
+
218
+ def response_auth_header
219
+ @response_auth_header ||= ""
220
+ end
221
+
222
+ def with_auth
223
+ retried ||= false
224
+ yield
225
+ rescue UnauthorizedAccess => e
226
+ raise if retried || auth_type != :digest
227
+ @response_auth_header = e.response["WWW-Authenticate"]
228
+ retried = true
229
+ retry
230
+ end
231
+
232
+ def authorization_header(http_method, uri)
233
+ if @user || @password
234
+ if auth_type == :digest
235
+ { "Authorization" => digest_auth_header(http_method, uri) }
236
+ else
237
+ { "Authorization" => "Basic " + ["#{@user}:#{@password}"].pack("m").delete("\r\n") }
238
+ end
239
+ elsif @bearer_token
240
+ { "Authorization" => "Bearer #{@bearer_token}" }
241
+ else
242
+ {}
243
+ end
244
+ end
245
+
246
+ def digest_auth_header(http_method, uri)
247
+ params = extract_params_from_response
248
+
249
+ request_uri = uri.path
250
+ request_uri << "?#{uri.query}" if uri.query
251
+
252
+ ha1 = Digest::MD5.hexdigest("#{@user}:#{params['realm']}:#{@password}")
253
+ ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{request_uri}")
254
+
255
+ params["cnonce"] = client_nonce
256
+ request_digest = Digest::MD5.hexdigest([ha1, params["nonce"], "0", params["cnonce"], params["qop"], ha2].join(":"))
257
+ "Digest #{auth_attributes_for(uri, request_digest, params)}"
258
+ end
259
+
260
+ def client_nonce
261
+ Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
262
+ end
263
+
264
+ def extract_params_from_response
265
+ params = {}
266
+ if response_auth_header =~ /^(\w+) (.*)/
267
+ $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
268
+ end
269
+ params
270
+ end
271
+
272
+ def auth_attributes_for(uri, request_digest, params)
273
+ auth_attrs =
274
+ [
275
+ %Q(username="#{@user}"),
276
+ %Q(realm="#{params['realm']}"),
277
+ %Q(qop="#{params['qop']}"),
278
+ %Q(uri="#{uri.path}"),
279
+ %Q(nonce="#{params['nonce']}"),
280
+ 'nc="0"',
281
+ %Q(cnonce="#{params['cnonce']}"),
282
+ %Q(response="#{request_digest}")]
283
+
284
+ auth_attrs << %Q(opaque="#{params['opaque']}") unless params["opaque"].blank?
285
+ auth_attrs.join(", ")
286
+ end
287
+
288
+ def http_format_header(http_method)
289
+ { HTTP_FORMAT_HEADER_NAMES[http_method] => format.mime_type }
290
+ end
291
+
292
+ def legitimize_auth_type(auth_type)
293
+ return :basic if auth_type.nil?
294
+ auth_type = auth_type.to_sym
295
+ auth_type.in?([:basic, :digest, :bearer]) ? auth_type : :basic
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/blank"
4
+
5
+ module ActiveResource
6
+ # A module to support custom REST methods and sub-resources, allowing you to break out
7
+ # of the "default" REST methods with your own custom resource requests. For example,
8
+ # say you use Rails to expose a REST service and configure your routes with:
9
+ #
10
+ # map.resources :people, :new => { :register => :post },
11
+ # :member => { :promote => :put, :deactivate => :delete }
12
+ # :collection => { :active => :get }
13
+ #
14
+ # This route set creates routes for the following HTTP requests:
15
+ #
16
+ # POST /people/new/register.json # PeopleController.register
17
+ # PATCH/PUT /people/1/promote.json # PeopleController.promote with :id => 1
18
+ # DELETE /people/1/deactivate.json # PeopleController.deactivate with :id => 1
19
+ # GET /people/active.json # PeopleController.active
20
+ #
21
+ # Using this module, Active Resource can use these custom REST methods just like the
22
+ # standard methods.
23
+ #
24
+ # class Person < ActiveResource::Base
25
+ # self.site = "https://37s.sunrise.com"
26
+ # end
27
+ #
28
+ # Person.new(:name => 'Ryan').post(:register) # POST /people/new/register.json
29
+ # # => { :id => 1, :name => 'Ryan' }
30
+ #
31
+ # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.json
32
+ # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.json
33
+ #
34
+ # Person.get(:active) # GET /people/active.json
35
+ # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
36
+ #
37
+ module CustomMethods
38
+ extend ActiveSupport::Concern
39
+
40
+ included do
41
+ class << self
42
+ alias :orig_delete :delete
43
+
44
+ # Invokes a GET to a given custom REST method. For example:
45
+ #
46
+ # Person.get(:active) # GET /people/active.json
47
+ # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
48
+ #
49
+ # Person.get(:active, :awesome => true) # GET /people/active.json?awesome=true
50
+ # # => [{:id => 1, :name => 'Ryan'}]
51
+ #
52
+ # Note: the objects returned from this method are not automatically converted
53
+ # into ActiveResource::Base instances - they are ordinary Hashes. If you are expecting
54
+ # ActiveResource::Base instances, use the <tt>find</tt> class method with the
55
+ # <tt>:from</tt> option. For example:
56
+ #
57
+ # Person.find(:all, :from => :active)
58
+ def get(custom_method_name, options = {})
59
+ hashified = format.decode(connection.get(custom_method_collection_url(custom_method_name, options), headers).body)
60
+ derooted = Formats.remove_root(hashified)
61
+ derooted.is_a?(Array) ? derooted.map { |e| Formats.remove_root(e) } : derooted
62
+ end
63
+
64
+ def post(custom_method_name, options = {}, body = "")
65
+ connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
66
+ end
67
+
68
+ def patch(custom_method_name, options = {}, body = "")
69
+ connection.patch(custom_method_collection_url(custom_method_name, options), body, headers)
70
+ end
71
+
72
+ def put(custom_method_name, options = {}, body = "")
73
+ connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
74
+ end
75
+
76
+ def delete(custom_method_name, options = {})
77
+ # Need to jump through some hoops to retain the original class 'delete' method
78
+ if custom_method_name.is_a?(Symbol)
79
+ connection.delete(custom_method_collection_url(custom_method_name, options), headers)
80
+ else
81
+ orig_delete(custom_method_name, options)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ module ClassMethods
88
+ def custom_method_collection_url(method_name, options = {})
89
+ prefix_options, query_options = split_options(options)
90
+ "#{prefix(prefix_options)}#{collection_name}/#{method_name}#{format_extension}#{query_string(query_options)}"
91
+ end
92
+ end
93
+
94
+ def get(method_name, options = {})
95
+ self.class.format.decode(connection.get(custom_method_element_url(method_name, options), self.class.headers).body)
96
+ end
97
+
98
+ def post(method_name, options = {}, body = nil)
99
+ request_body = body.blank? ? encode : body
100
+ if new?
101
+ connection.post(custom_method_new_element_url(method_name, options), request_body, self.class.headers)
102
+ else
103
+ connection.post(custom_method_element_url(method_name, options), request_body, self.class.headers)
104
+ end
105
+ end
106
+
107
+ def patch(method_name, options = {}, body = "")
108
+ connection.patch(custom_method_element_url(method_name, options), body, self.class.headers)
109
+ end
110
+
111
+ def put(method_name, options = {}, body = "")
112
+ connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
113
+ end
114
+
115
+ def delete(method_name, options = {})
116
+ connection.delete(custom_method_element_url(method_name, options), self.class.headers)
117
+ end
118
+
119
+
120
+ private
121
+ def custom_method_element_url(method_name, options = {})
122
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{URI.encode_www_form_component(id.to_s)}/#{method_name}#{self.class.format_extension}#{self.class.__send__(:query_string, options)}"
123
+ end
124
+
125
+ def custom_method_new_element_url(method_name, options = {})
126
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}#{self.class.format_extension}#{self.class.__send__(:query_string, options)}"
127
+ end
128
+ end
129
+ end