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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.standard.yml +2 -0
- data/CHANGELOG.md +5 -0
- data/README.md +45 -0
- data/Rakefile +21 -0
- data/example/consumer/.dockerignore +41 -0
- data/example/consumer/.gitattributes +9 -0
- data/example/consumer/.gitignore +36 -0
- data/example/consumer/.kamal/hooks/docker-setup.sample +3 -0
- data/example/consumer/.kamal/hooks/post-deploy.sample +14 -0
- data/example/consumer/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/example/consumer/.kamal/hooks/pre-build.sample +51 -0
- data/example/consumer/.kamal/hooks/pre-connect.sample +47 -0
- data/example/consumer/.kamal/hooks/pre-deploy.sample +109 -0
- data/example/consumer/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/example/consumer/.kamal/secrets +17 -0
- data/example/consumer/Dockerfile +65 -0
- data/example/consumer/Gemfile +17 -0
- data/example/consumer/Rakefile +6 -0
- data/example/consumer/app/controllers/application_controller.rb +2 -0
- data/example/consumer/app/controllers/concerns/.keep +0 -0
- data/example/consumer/app/jobs/application_job.rb +7 -0
- data/example/consumer/app/mailers/application_mailer.rb +4 -0
- data/example/consumer/app/models/application_record.rb +3 -0
- data/example/consumer/app/models/concerns/.keep +0 -0
- data/example/consumer/app/models/person.rb +9 -0
- data/example/consumer/app/views/layouts/mailer.html.erb +13 -0
- data/example/consumer/app/views/layouts/mailer.text.erb +1 -0
- data/example/consumer/bin/brakeman +7 -0
- data/example/consumer/bin/bundle +109 -0
- data/example/consumer/bin/dev +2 -0
- data/example/consumer/bin/docker-entrypoint +14 -0
- data/example/consumer/bin/jobs +6 -0
- data/example/consumer/bin/kamal +27 -0
- data/example/consumer/bin/rails +4 -0
- data/example/consumer/bin/rake +4 -0
- data/example/consumer/bin/rubocop +8 -0
- data/example/consumer/bin/setup +34 -0
- data/example/consumer/bin/thrust +5 -0
- data/example/consumer/config/application.rb +20 -0
- data/example/consumer/config/boot.rb +3 -0
- data/example/consumer/config/cache.yml +16 -0
- data/example/consumer/config/credentials.yml.enc +1 -0
- data/example/consumer/config/database.yml +14 -0
- data/example/consumer/config/deploy.yml +116 -0
- data/example/consumer/config/environment.rb +5 -0
- data/example/consumer/config/environments/development.rb +64 -0
- data/example/consumer/config/environments/production.rb +85 -0
- data/example/consumer/config/environments/test.rb +50 -0
- data/example/consumer/config/initializers/cors.rb +16 -0
- data/example/consumer/config/initializers/filter_parameter_logging.rb +8 -0
- data/example/consumer/config/initializers/inflections.rb +16 -0
- data/example/consumer/config/locales/en.yml +31 -0
- data/example/consumer/config/puma.rb +41 -0
- data/example/consumer/config/queue.yml +18 -0
- data/example/consumer/config/recurring.yml +10 -0
- data/example/consumer/config/routes.rb +10 -0
- data/example/consumer/config.ru +6 -0
- data/example/consumer/db/cache_schema.rb +14 -0
- data/example/consumer/db/queue_schema.rb +129 -0
- data/example/consumer/db/seeds.rb +0 -0
- data/example/consumer/lib/tasks/.keep +0 -0
- data/example/consumer/log/.keep +0 -0
- data/example/consumer/public/robots.txt +1 -0
- data/example/consumer/script/.keep +0 -0
- data/example/consumer/storage/.keep +0 -0
- data/example/consumer/tmp/.keep +0 -0
- data/example/consumer/tmp/cache/.keep +0 -0
- data/example/consumer/tmp/pids/.keep +0 -0
- data/example/consumer/tmp/storage/.keep +0 -0
- data/example/consumer/vendor/.keep +0 -0
- data/example/provider/.dockerignore +41 -0
- data/example/provider/.gitattributes +9 -0
- data/example/provider/.gitignore +32 -0
- data/example/provider/.kamal/hooks/docker-setup.sample +3 -0
- data/example/provider/.kamal/hooks/post-deploy.sample +14 -0
- data/example/provider/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/example/provider/.kamal/hooks/pre-build.sample +51 -0
- data/example/provider/.kamal/hooks/pre-connect.sample +47 -0
- data/example/provider/.kamal/hooks/pre-deploy.sample +109 -0
- data/example/provider/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/example/provider/.kamal/secrets +17 -0
- data/example/provider/Dockerfile +65 -0
- data/example/provider/Gemfile +14 -0
- data/example/provider/Rakefile +6 -0
- data/example/provider/app/controllers/application_controller.rb +2 -0
- data/example/provider/app/controllers/concerns/.keep +0 -0
- data/example/provider/app/controllers/people_controller.rb +68 -0
- data/example/provider/app/jobs/application_job.rb +7 -0
- data/example/provider/app/mailers/application_mailer.rb +4 -0
- data/example/provider/app/models/address.rb +3 -0
- data/example/provider/app/models/application_record.rb +3 -0
- data/example/provider/app/models/company.rb +3 -0
- data/example/provider/app/models/concerns/.keep +0 -0
- data/example/provider/app/models/person.rb +6 -0
- data/example/provider/app/views/layouts/mailer.html.erb +13 -0
- data/example/provider/app/views/layouts/mailer.text.erb +1 -0
- data/example/provider/bin/brakeman +7 -0
- data/example/provider/bin/bundle +109 -0
- data/example/provider/bin/dev +2 -0
- data/example/provider/bin/docker-entrypoint +14 -0
- data/example/provider/bin/jobs +6 -0
- data/example/provider/bin/kamal +27 -0
- data/example/provider/bin/rails +4 -0
- data/example/provider/bin/rake +4 -0
- data/example/provider/bin/rubocop +8 -0
- data/example/provider/bin/setup +34 -0
- data/example/provider/bin/thrust +5 -0
- data/example/provider/config/application.rb +44 -0
- data/example/provider/config/boot.rb +3 -0
- data/example/provider/config/cache.yml +16 -0
- data/example/provider/config/credentials.yml.enc +1 -0
- data/example/provider/config/database.yml +20 -0
- data/example/provider/config/deploy.yml +116 -0
- data/example/provider/config/environment.rb +5 -0
- data/example/provider/config/environments/development.rb +64 -0
- data/example/provider/config/environments/production.rb +85 -0
- data/example/provider/config/environments/test.rb +50 -0
- data/example/provider/config/initializers/cors.rb +16 -0
- data/example/provider/config/initializers/filter_parameter_logging.rb +8 -0
- data/example/provider/config/initializers/inflections.rb +16 -0
- data/example/provider/config/locales/en.yml +31 -0
- data/example/provider/config/puma.rb +41 -0
- data/example/provider/config/queue.yml +18 -0
- data/example/provider/config/recurring.yml +10 -0
- data/example/provider/config/routes.rb +4 -0
- data/example/provider/config.ru +6 -0
- data/example/provider/db/cache_schema.rb +14 -0
- data/example/provider/db/migrate/20241202183937_create_people.rb +11 -0
- data/example/provider/db/migrate/20241202183955_create_addresses.rb +13 -0
- data/example/provider/db/migrate/20241202184017_create_companies.rb +14 -0
- data/example/provider/db/queue_schema.rb +129 -0
- data/example/provider/db/schema.rb +47 -0
- data/example/provider/db/seeds.rb +18 -0
- data/example/provider/lib/tasks/.keep +0 -0
- data/example/provider/log/.keep +0 -0
- data/example/provider/public/robots.txt +1 -0
- data/example/provider/script/.keep +0 -0
- data/example/provider/storage/.keep +0 -0
- data/example/provider/tmp/.keep +0 -0
- data/example/provider/tmp/pids/.keep +0 -0
- data/example/provider/tmp/storage/.keep +0 -0
- data/example/provider/vendor/.keep +0 -0
- data/lib/active_cached_resource/caching.rb +176 -0
- data/lib/active_cached_resource/caching_strategies/active_support_cache.rb +31 -0
- data/lib/active_cached_resource/caching_strategies/base.rb +114 -0
- data/lib/active_cached_resource/caching_strategies/sql_cache.rb +32 -0
- data/lib/active_cached_resource/configuration.rb +50 -0
- data/lib/active_cached_resource/logger.rb +22 -0
- data/lib/active_cached_resource/model.rb +33 -0
- data/lib/active_cached_resource/version.rb +12 -0
- data/lib/active_cached_resource.rb +64 -0
- data/lib/activeresource/.gitignore +15 -0
- data/lib/activeresource/README.md +283 -0
- data/lib/activeresource/examples/performance.rb +72 -0
- data/lib/activeresource/lib/active_resource/active_job_serializer.rb +26 -0
- data/lib/activeresource/lib/active_resource/associations/builder/association.rb +32 -0
- data/lib/activeresource/lib/active_resource/associations/builder/belongs_to.rb +16 -0
- data/lib/activeresource/lib/active_resource/associations/builder/has_many.rb +14 -0
- data/lib/activeresource/lib/active_resource/associations/builder/has_one.rb +14 -0
- data/lib/activeresource/lib/active_resource/associations.rb +175 -0
- data/lib/activeresource/lib/active_resource/base.rb +1741 -0
- data/lib/activeresource/lib/active_resource/callbacks.rb +22 -0
- data/lib/activeresource/lib/active_resource/collection.rb +214 -0
- data/lib/activeresource/lib/active_resource/connection.rb +298 -0
- data/lib/activeresource/lib/active_resource/custom_methods.rb +129 -0
- data/lib/activeresource/lib/active_resource/exceptions.rb +98 -0
- data/lib/activeresource/lib/active_resource/formats/json_format.rb +28 -0
- data/lib/activeresource/lib/active_resource/formats/xml_format.rb +27 -0
- data/lib/activeresource/lib/active_resource/formats.rb +24 -0
- data/lib/activeresource/lib/active_resource/http_mock.rb +386 -0
- data/lib/activeresource/lib/active_resource/inheriting_hash.rb +34 -0
- data/lib/activeresource/lib/active_resource/log_subscriber.rb +26 -0
- data/lib/activeresource/lib/active_resource/railtie.rb +31 -0
- data/lib/activeresource/lib/active_resource/reflection.rb +78 -0
- data/lib/activeresource/lib/active_resource/schema.rb +60 -0
- data/lib/activeresource/lib/active_resource/singleton.rb +111 -0
- data/lib/activeresource/lib/active_resource/threadsafe_attributes.rb +65 -0
- data/lib/activeresource/lib/active_resource/validations.rb +176 -0
- data/lib/activeresource/lib/active_resource.rb +49 -0
- data/lib/activeresource/lib/activeresource.rb +3 -0
- data/lib/activeresource/test/abstract_unit.rb +153 -0
- data/lib/activeresource/test/cases/active_job_serializer_test.rb +53 -0
- data/lib/activeresource/test/cases/association_test.rb +104 -0
- data/lib/activeresource/test/cases/associations/builder/belongs_to_test.rb +42 -0
- data/lib/activeresource/test/cases/associations/builder/has_many_test.rb +28 -0
- data/lib/activeresource/test/cases/associations/builder/has_one_test.rb +28 -0
- data/lib/activeresource/test/cases/authorization_test.rb +276 -0
- data/lib/activeresource/test/cases/base/custom_methods_test.rb +155 -0
- data/lib/activeresource/test/cases/base/equality_test.rb +53 -0
- data/lib/activeresource/test/cases/base/load_test.rb +249 -0
- data/lib/activeresource/test/cases/base/schema_test.rb +428 -0
- data/lib/activeresource/test/cases/base_errors_test.rb +129 -0
- data/lib/activeresource/test/cases/base_test.rb +1622 -0
- data/lib/activeresource/test/cases/callbacks_test.rb +155 -0
- data/lib/activeresource/test/cases/collection_test.rb +172 -0
- data/lib/activeresource/test/cases/connection_test.rb +357 -0
- data/lib/activeresource/test/cases/finder_test.rb +217 -0
- data/lib/activeresource/test/cases/format_test.rb +137 -0
- data/lib/activeresource/test/cases/http_mock_test.rb +213 -0
- data/lib/activeresource/test/cases/inheritence_test.rb +19 -0
- data/lib/activeresource/test/cases/inheriting_hash_test.rb +25 -0
- data/lib/activeresource/test/cases/log_subscriber_test.rb +63 -0
- data/lib/activeresource/test/cases/reflection_test.rb +65 -0
- data/lib/activeresource/test/cases/validations_test.rb +78 -0
- data/lib/activeresource/test/fixtures/address.rb +20 -0
- data/lib/activeresource/test/fixtures/beast.rb +16 -0
- data/lib/activeresource/test/fixtures/comment.rb +5 -0
- data/lib/activeresource/test/fixtures/customer.rb +5 -0
- data/lib/activeresource/test/fixtures/inventory.rb +14 -0
- data/lib/activeresource/test/fixtures/person.rb +15 -0
- data/lib/activeresource/test/fixtures/pet.rb +6 -0
- data/lib/activeresource/test/fixtures/post.rb +5 -0
- data/lib/activeresource/test/fixtures/product.rb +11 -0
- data/lib/activeresource/test/fixtures/project.rb +19 -0
- data/lib/activeresource/test/fixtures/proxy.rb +6 -0
- data/lib/activeresource/test/fixtures/sound.rb +11 -0
- data/lib/activeresource/test/fixtures/street_address.rb +6 -0
- data/lib/activeresource/test/fixtures/subscription_plan.rb +7 -0
- data/lib/activeresource/test/fixtures/weather.rb +21 -0
- data/lib/activeresource/test/setter_trap.rb +28 -0
- data/lib/activeresource/test/singleton_test.rb +138 -0
- data/lib/activeresource/test/threadsafe_attributes_test.rb +91 -0
- data/lib/generators/active_cached_resource/install_generator.rb +31 -0
- data/lib/generators/active_cached_resource/templates/migration.erb +16 -0
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/.gitattributes +1 -0
- data/sorbet/rbi/annotations/activemodel.rbi +89 -0
- data/sorbet/rbi/annotations/activesupport.rbi +457 -0
- data/sorbet/rbi/annotations/minitest.rbi +119 -0
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/dsl/.gitattributes +1 -0
- data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/actioncable@8.0.0.rbi +252 -0
- data/sorbet/rbi/gems/actionmailbox@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionmailer@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionpack@8.0.0.rbi +20909 -0
- data/sorbet/rbi/gems/actiontext@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionview@8.0.0.rbi +16207 -0
- data/sorbet/rbi/gems/activejob@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/activemodel-serializers-xml@1.0.3.rbi +166 -0
- data/sorbet/rbi/gems/activemodel@8.0.0.rbi +6857 -0
- data/sorbet/rbi/gems/activerecord@8.0.0.rbi +42896 -0
- data/sorbet/rbi/gems/activeresource@6.1.4.rbi +3944 -0
- data/sorbet/rbi/gems/activestorage@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/activesupport@8.0.0.rbi +21251 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
- data/sorbet/rbi/gems/base64@0.2.0.rbi +509 -0
- data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
- data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +78 -0
- data/sorbet/rbi/gems/builder@3.3.0.rbi +9 -0
- data/sorbet/rbi/gems/bump@0.10.0.rbi +169 -0
- data/sorbet/rbi/gems/byebug@11.1.3.rbi +3607 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +3427 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.3.4.rbi +11645 -0
- data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +9 -0
- data/sorbet/rbi/gems/crass@1.0.6.rbi +623 -0
- data/sorbet/rbi/gems/date@3.4.0.rbi +75 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.1.rbi +1131 -0
- data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
- data/sorbet/rbi/gems/drb@2.2.1.rbi +1347 -0
- data/sorbet/rbi/gems/erubi@1.13.0.rbi +150 -0
- data/sorbet/rbi/gems/globalid@1.2.1.rbi +9 -0
- data/sorbet/rbi/gems/i18n@1.14.6.rbi +2359 -0
- data/sorbet/rbi/gems/io-console@0.7.2.rbi +9 -0
- data/sorbet/rbi/gems/json@2.8.2.rbi +1901 -0
- data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14238 -0
- data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
- data/sorbet/rbi/gems/logger@1.6.1.rbi +920 -0
- data/sorbet/rbi/gems/loofah@2.23.1.rbi +1081 -0
- data/sorbet/rbi/gems/mail@2.8.1.rbi +9 -0
- data/sorbet/rbi/gems/marcel@1.0.4.rbi +9 -0
- data/sorbet/rbi/gems/method_source@1.1.0.rbi +304 -0
- data/sorbet/rbi/gems/mini_mime@1.1.5.rbi +9 -0
- data/sorbet/rbi/gems/minitest@5.25.2.rbi +1547 -0
- data/sorbet/rbi/gems/net-imap@0.5.1.rbi +9 -0
- data/sorbet/rbi/gems/net-pop@0.1.2.rbi +9 -0
- data/sorbet/rbi/gems/net-protocol@0.2.2.rbi +292 -0
- data/sorbet/rbi/gems/net-smtp@0.5.0.rbi +9 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/nio4r@2.7.4.rbi +9 -0
- data/sorbet/rbi/gems/nokogiri@1.16.7.rbi +7311 -0
- data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
- data/sorbet/rbi/gems/parser@3.3.6.0.rbi +5519 -0
- data/sorbet/rbi/gems/prism@1.2.0.rbi +39085 -0
- data/sorbet/rbi/gems/pry-byebug@3.10.1.rbi +1151 -0
- data/sorbet/rbi/gems/pry@0.14.2.rbi +10076 -0
- data/sorbet/rbi/gems/psych@5.2.0.rbi +1785 -0
- data/sorbet/rbi/gems/racc@1.8.1.rbi +162 -0
- data/sorbet/rbi/gems/rack-session@2.0.0.rbi +727 -0
- data/sorbet/rbi/gems/rack-test@2.1.0.rbi +747 -0
- data/sorbet/rbi/gems/rack@3.1.8.rbi +4905 -0
- data/sorbet/rbi/gems/rackup@2.2.1.rbi +230 -0
- data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +758 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +785 -0
- data/sorbet/rbi/gems/rails@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/railties@8.0.0.rbi +6287 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
- data/sorbet/rbi/gems/rake@13.2.1.rbi +3091 -0
- data/sorbet/rbi/gems/rbi@0.2.1.rbi +4535 -0
- data/sorbet/rbi/gems/rdoc@6.8.1.rbi +12572 -0
- data/sorbet/rbi/gems/regexp_parser@2.9.2.rbi +3772 -0
- data/sorbet/rbi/gems/reline@0.5.12.rbi +2416 -0
- data/sorbet/rbi/gems/rexml@3.3.9.rbi +4858 -0
- data/sorbet/rbi/gems/rspec-core@3.13.2.rbi +11287 -0
- data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
- data/sorbet/rbi/gems/rspec-mocks@3.13.2.rbi +5341 -0
- data/sorbet/rbi/gems/rspec-support@3.13.1.rbi +1630 -0
- data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
- data/sorbet/rbi/gems/rubocop-ast@1.36.1.rbi +7303 -0
- data/sorbet/rbi/gems/rubocop-performance@1.21.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop@1.65.1.rbi +58170 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
- data/sorbet/rbi/gems/securerandom@0.3.2.rbi +395 -0
- data/sorbet/rbi/gems/simplecov-html@0.13.1.rbi +225 -0
- data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2149 -0
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
- data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
- data/sorbet/rbi/gems/standard-custom@1.0.2.rbi +9 -0
- data/sorbet/rbi/gems/standard-performance@1.4.0.rbi +9 -0
- data/sorbet/rbi/gems/standard@1.40.0.rbi +929 -0
- data/sorbet/rbi/gems/stringio@3.1.2.rbi +9 -0
- data/sorbet/rbi/gems/tapioca@0.16.4.rbi +3597 -0
- data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
- data/sorbet/rbi/gems/timeout@0.4.2.rbi +151 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
- data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
- data/sorbet/rbi/gems/uri@1.0.2.rbi +2377 -0
- data/sorbet/rbi/gems/useragent@0.16.10.rbi +9 -0
- data/sorbet/rbi/gems/websocket-driver@0.7.6.rbi +9 -0
- data/sorbet/rbi/gems/websocket-extensions@0.1.5.rbi +9 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18504 -0
- data/sorbet/rbi/gems/zeitwerk@2.7.1.rbi +9 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +12 -0
- metadata +543 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
module ActiveCachedResource
|
|
2
|
+
module Caching
|
|
3
|
+
GLOBAL_PREFIX = "acr"
|
|
4
|
+
RELOAD_PARAM = :_acr_reload
|
|
5
|
+
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class << self
|
|
10
|
+
alias_method :find_without_cache, :find
|
|
11
|
+
alias_method :find, :find_with_cache
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module ClassMethods
|
|
16
|
+
def find_with_cache(*orig_args)
|
|
17
|
+
args = orig_args.deep_dup # Avoid mutating original arguments
|
|
18
|
+
options = extract_options(*args)
|
|
19
|
+
|
|
20
|
+
should_reload = options.delete(:reload) || !cached_resource.enabled
|
|
21
|
+
|
|
22
|
+
# When bypassing cache, include the reload option as a query parameter for collection requests.
|
|
23
|
+
# Hacky but this way ActiveResource::Collection#request_resources! can access it
|
|
24
|
+
if should_reload && args.first == :all
|
|
25
|
+
options[:params] = {} if options[:params].blank?
|
|
26
|
+
options[:params][RELOAD_PARAM] = should_reload
|
|
27
|
+
args << options
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if args.first == :all
|
|
31
|
+
# Let ActiveResource::Collection handle the caching so that lazy loading is more effective
|
|
32
|
+
return find_via_reload(*args)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
should_reload ? find_via_reload(*args) : find_via_cache(*args)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Clear the cache.
|
|
39
|
+
def clear
|
|
40
|
+
cached_resource.cache.clear("#{cache_key_prefix}/")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def cache_read(*)
|
|
46
|
+
key = cache_key(*)
|
|
47
|
+
json_string = nil
|
|
48
|
+
begin
|
|
49
|
+
json_string = cached_resource.cache.read(key)
|
|
50
|
+
rescue => e
|
|
51
|
+
cached_resource.logger.error("[KEY:#{key}] Failed to read from cache: #{e.message} #{e.backtrace.join(" | ")}")
|
|
52
|
+
json_string = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
return nil if json_string.nil?
|
|
56
|
+
|
|
57
|
+
cached_resource.logger.debug("[KEY:#{key}] Cache hit")
|
|
58
|
+
json_to_object(json_string)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def cache_write(object, *)
|
|
62
|
+
cache_options = {expires_in: cached_resource.ttl}
|
|
63
|
+
cache_value = object_to_json(object, *)
|
|
64
|
+
key = cache_key(*)
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
cached_resource.cache.write(key, cache_value, cache_options)
|
|
68
|
+
true
|
|
69
|
+
rescue => e
|
|
70
|
+
cached_resource.logger.error("[KEY:#{key}] Failed to write to cache: #{e.message} #{e.backtrace.join(" | ")}")
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def find_via_cache(*)
|
|
76
|
+
cache_read(*) || find_via_reload(*)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def find_via_reload(*)
|
|
80
|
+
object = find_without_cache(*)
|
|
81
|
+
return object unless should_cache?(object)
|
|
82
|
+
|
|
83
|
+
cache_write(object, *)
|
|
84
|
+
object
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Determines if the given object should be cached.
|
|
88
|
+
#
|
|
89
|
+
# @param object [Object, ActiveResource::Collection] The object to check for caching eligibility.
|
|
90
|
+
# @return [Boolean] Returns true if the object should be cached, false otherwise.
|
|
91
|
+
def should_cache?(object)
|
|
92
|
+
return false unless cached_resource.enabled
|
|
93
|
+
|
|
94
|
+
# Calling `present?` on the `collection_parser`, an instance or descendent of
|
|
95
|
+
# `ActiveResource::Collection` will trigger a request.
|
|
96
|
+
# Checking if `requested?` first, will prevent an unnecessary network request when calling `present?`.
|
|
97
|
+
case object
|
|
98
|
+
when ActiveResource::Collection
|
|
99
|
+
object.requested? && object.present?
|
|
100
|
+
else
|
|
101
|
+
object.present?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def cache_key(*args)
|
|
106
|
+
"#{name_key}/#{args.join("/")}".downcase.delete(" ")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def name_key
|
|
110
|
+
# `cache_key_prefix` is separated from key parts with a dash to easily distinguish the prefix
|
|
111
|
+
"#{cache_key_prefix}-" + name.parameterize.tr("-", "/")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def cache_key_prefix
|
|
115
|
+
prefix = cached_resource.cache_key_prefix
|
|
116
|
+
|
|
117
|
+
if prefix.respond_to?(:call)
|
|
118
|
+
result = prefix.call
|
|
119
|
+
if !result.is_a?(String) || result.empty?
|
|
120
|
+
raise ArgumentError, "cache_key_prefix must return a non-empty String"
|
|
121
|
+
end
|
|
122
|
+
"#{GLOBAL_PREFIX}/#{result}"
|
|
123
|
+
else
|
|
124
|
+
"#{GLOBAL_PREFIX}/#{prefix}"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def json_to_object(json_string)
|
|
129
|
+
object = ActiveSupport::JSON.decode(json_string)
|
|
130
|
+
resource = object["resource"]
|
|
131
|
+
|
|
132
|
+
case resource
|
|
133
|
+
when Array
|
|
134
|
+
resource.map do |attrs|
|
|
135
|
+
new(attrs["object"], attrs["persistence"]).tap do |r|
|
|
136
|
+
r.prefix_options = object["prefix_options"]
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
new(resource["object"], resource["persistence"]).tap do |r|
|
|
141
|
+
r.prefix_options = object["prefix_options"]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def object_to_json(object, *)
|
|
147
|
+
options = extract_options(*)
|
|
148
|
+
params = options.fetch(:params, {})
|
|
149
|
+
prefix_options, query_options = split_options(params)
|
|
150
|
+
json_object = if object.is_a? Enumerable
|
|
151
|
+
{
|
|
152
|
+
resource: object.map { |o| {object: o, persistence: o.persisted?} },
|
|
153
|
+
prefix_options: prefix_options,
|
|
154
|
+
path_params: params,
|
|
155
|
+
query_params: query_options
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{
|
|
159
|
+
resource: {object: object, persistence: object.persisted?},
|
|
160
|
+
prefix_options: prefix_options
|
|
161
|
+
}
|
|
162
|
+
end
|
|
163
|
+
ActiveSupport::JSON.encode(json_object)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Extract options without mutating the original arguments.
|
|
167
|
+
def extract_options(*args)
|
|
168
|
+
if (last = args.last) && last.try(:extractable_options?)
|
|
169
|
+
last
|
|
170
|
+
else
|
|
171
|
+
{}
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module ActiveCachedResource
|
|
4
|
+
module CachingStrategies
|
|
5
|
+
class ActiveSupportCache < Base
|
|
6
|
+
def initialize(cache_store)
|
|
7
|
+
super()
|
|
8
|
+
@cache_store = cache_store
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
|
|
13
|
+
def read_raw(key)
|
|
14
|
+
@cache_store.read(key)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def write_raw(key, compressed_value, options)
|
|
18
|
+
@cache_store.write(key, compressed_value, options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def clear_raw(pattern)
|
|
22
|
+
if @cache_store.respond_to?(:delete_matched)
|
|
23
|
+
@cache_store.delete_matched("#{pattern}*")
|
|
24
|
+
true
|
|
25
|
+
else
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require "msgpack"
|
|
2
|
+
module ActiveCachedResource
|
|
3
|
+
module CachingStrategies
|
|
4
|
+
class Base
|
|
5
|
+
# Reads the value associated with the given key from the cache.
|
|
6
|
+
#
|
|
7
|
+
# @param key [String, Symbol] the key to read from the cache.
|
|
8
|
+
#
|
|
9
|
+
# @return [Object, nil] the decompressed value associated with the key, or nil if the key is not found.
|
|
10
|
+
def read(key)
|
|
11
|
+
raise ArgumentError, "key must be a String or Symbol" unless key.is_a?(String) || key.is_a?(Symbol)
|
|
12
|
+
raw_value = read_raw(hash_key(key))
|
|
13
|
+
raw_value && decompress(raw_value)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Writes an object to the cache with the specified key and options.
|
|
17
|
+
#
|
|
18
|
+
# @param key [String, Symbol] The key used to store the object in the cache.
|
|
19
|
+
# @param value [String] The value to be stored in the cache.
|
|
20
|
+
# @param options [Hash] Options for the cache write operation. Must include `:expires_in`.
|
|
21
|
+
# @option options [Integer] :expires_in The expiration time in seconds for the cached object. (required)
|
|
22
|
+
#
|
|
23
|
+
# @raise [ArgumentError] If the `:expires_in` option is missing.
|
|
24
|
+
#
|
|
25
|
+
# @return [Boolean] `true` if the object was successfully written to the cache, `false` otherwise.
|
|
26
|
+
def write(key, value, options)
|
|
27
|
+
raise ArgumentError, "`expires_in` option is required" unless options[:expires_in]
|
|
28
|
+
|
|
29
|
+
write_raw(hash_key(key), compress(value), options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Clears the cache based on the given pattern.
|
|
33
|
+
#
|
|
34
|
+
# @param pattern [String] the pattern to match cache keys that need to be cleared.
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean] `true` if the cache was successfully cleared, `false` otherwise.
|
|
37
|
+
def clear(pattern)
|
|
38
|
+
clear_raw(pattern)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
protected
|
|
42
|
+
|
|
43
|
+
# Reads the value associated with the given key from the cache.
|
|
44
|
+
#
|
|
45
|
+
# @param key [Object] the key to read from the cache.
|
|
46
|
+
#
|
|
47
|
+
# @note This method must be implemented by the subclass.
|
|
48
|
+
#
|
|
49
|
+
# @return [Object, nil] the decompressed value associated with the key, or nil if the key is not found.
|
|
50
|
+
def read_raw(key)
|
|
51
|
+
raise NotImplementedError, "#{self.class} must implement `read_raw`"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Writes an object to the cache with the specified key and options.
|
|
55
|
+
#
|
|
56
|
+
# @param key [String, Symbol] The key used to store the object in the cache.
|
|
57
|
+
# @param value [String] The value to be stored in the cache.
|
|
58
|
+
# @param options [Hash] Options for the cache write operation. Must include `:expires_in`.
|
|
59
|
+
# @option options [Integer] :expires_in The expiration time in seconds for the cached object. (required)
|
|
60
|
+
#
|
|
61
|
+
# @note This method must be implemented by the subclass.
|
|
62
|
+
#
|
|
63
|
+
# @return [Boolean] `true` if the object was successfully written to the cache, `false` otherwise.
|
|
64
|
+
def write_raw(key, value, options)
|
|
65
|
+
raise NotImplementedError, "#{self.class} must implement `write_raw`"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Clears cache entry for the given pattern.
|
|
69
|
+
#
|
|
70
|
+
# @param pattern [String, nil] The pattern representing the cache entry to be cleared.
|
|
71
|
+
#
|
|
72
|
+
# @note This method must be implemented by the subclass.
|
|
73
|
+
#
|
|
74
|
+
# @return [Boolean] `true` if the cache was successfully cleared, `false` otherwise.
|
|
75
|
+
def clear_raw(pattern)
|
|
76
|
+
raise NotImplementedError, "#{self.class} must implement `clear_raw`"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
# Generates a hashed key for caching purposes.
|
|
82
|
+
#
|
|
83
|
+
# The method splits the provided key into a prefix and the remaining part,
|
|
84
|
+
# then combines the prefix with a SHA256 hash of the remaining part.
|
|
85
|
+
# The resulting key is prefixed with a global prefix defined in the
|
|
86
|
+
# ActiveCachedResource::Caching module.
|
|
87
|
+
#
|
|
88
|
+
# @example Hashing a key
|
|
89
|
+
# hash_key("prefix-key") #=> "acr/prefix/Digest::SHA256.hexdigest(key)"
|
|
90
|
+
#
|
|
91
|
+
# @param key [String] the original key to be hashed. It is expected to have a prefix and the key separated by a dash.
|
|
92
|
+
# @return [String] the generated hashed key with the global prefix and the prefix from the original key.
|
|
93
|
+
def hash_key(key)
|
|
94
|
+
# Prefix of keys are expected to be the first part of key separated by a dash.
|
|
95
|
+
prefix, k = key.split("-", 2)
|
|
96
|
+
if prefix.nil? || k.nil?
|
|
97
|
+
raise ArgumentError, "Key must have a prefix and a key separated by a dash"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
"#{prefix}/" + Digest::SHA256.hexdigest(k)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def compress(value)
|
|
104
|
+
MessagePack.pack(value)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def decompress(value)
|
|
108
|
+
MessagePack.unpack(value)
|
|
109
|
+
rescue MessagePack::UnpackError
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module ActiveCachedResource
|
|
4
|
+
module CachingStrategies
|
|
5
|
+
class SQLCache < Base
|
|
6
|
+
def initialize(model, options = {})
|
|
7
|
+
super()
|
|
8
|
+
@model = model
|
|
9
|
+
@batch_clear_size = options.fetch(:batch_clear_size, 1000)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def read_raw(key)
|
|
15
|
+
record = @model.where(key: key).where(@model.arel_table[:expires_at].gt(Time.current)).first
|
|
16
|
+
record&.value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def write_raw(key, value, options = {})
|
|
20
|
+
expires_at = Time.current + options.fetch(:expires_in)
|
|
21
|
+
|
|
22
|
+
@model.create({key: key, value: value, expires_at: expires_at})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def clear_raw(pattern)
|
|
26
|
+
@model.where(@model.arel_table[:key].matches("#{pattern}%")).in_batches(of: @batch_clear_size) do |batch|
|
|
27
|
+
batch.delete_all
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require "ostruct"
|
|
2
|
+
require_relative "logger"
|
|
3
|
+
require_relative "caching_strategies/sql_cache"
|
|
4
|
+
require_relative "caching_strategies/active_support_cache"
|
|
5
|
+
require_relative "caching_strategies/base"
|
|
6
|
+
|
|
7
|
+
module ActiveCachedResource
|
|
8
|
+
class Configuration < OpenStruct
|
|
9
|
+
CACHING_STRATEGIES = {
|
|
10
|
+
active_record: ActiveCachedResource::CachingStrategies::SQLCache,
|
|
11
|
+
active_support: ActiveCachedResource::CachingStrategies::ActiveSupportCache
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
OPTIONS = %i[cache_key_prefix logger enabled ttl]
|
|
15
|
+
|
|
16
|
+
def initialize(model, options = {})
|
|
17
|
+
super(
|
|
18
|
+
{
|
|
19
|
+
cache: determine_cache_strategy(options[:cache_store], options[:cache_strategy]),
|
|
20
|
+
cache_key_prefix: model.name.underscore,
|
|
21
|
+
logger: ActiveCachedResource::Logger.new(model.name),
|
|
22
|
+
enabled: true,
|
|
23
|
+
ttl: 86400
|
|
24
|
+
}.merge(options.slice(*OPTIONS))
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def on!
|
|
29
|
+
self.enabled = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def off!
|
|
33
|
+
self.enabled = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def determine_cache_strategy(cache_store, cache_strategy)
|
|
39
|
+
if cache_store.is_a?(CachingStrategies::Base)
|
|
40
|
+
cache_store
|
|
41
|
+
elsif cache_strategy
|
|
42
|
+
CACHING_STRATEGIES.fetch(cache_strategy).new(cache_store)
|
|
43
|
+
else
|
|
44
|
+
raise ArgumentError, "cache_store must be a CachingStrategies::Base or cache_strategy must be provided"
|
|
45
|
+
end
|
|
46
|
+
rescue KeyError
|
|
47
|
+
raise ArgumentError, "Invalid cache strategy: #{cache_strategy}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "logger"
|
|
2
|
+
|
|
3
|
+
module ActiveCachedResource
|
|
4
|
+
class Logger < ::Logger
|
|
5
|
+
COLORS = {
|
|
6
|
+
debug: "\e[36m", # Blue
|
|
7
|
+
info: "\e[0m", # Default
|
|
8
|
+
warn: "\e[33m", # Yellow
|
|
9
|
+
error: "\e[31m", # Red
|
|
10
|
+
fatal: "\e[31m", # Red
|
|
11
|
+
reset: "\e[0m" # Reset
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
def initialize(model_name)
|
|
15
|
+
super($stdout)
|
|
16
|
+
@model_name = model_name
|
|
17
|
+
self.formatter = proc do |severity, datetime, _progname, msg|
|
|
18
|
+
"#{COLORS[severity.downcase.to_sym]}#{datetime} -- #{severity} [CACHE][ACR][#{model_name}] #{msg}#{COLORS[:reset]}\n"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "active_support/concern"
|
|
2
|
+
|
|
3
|
+
require_relative "caching"
|
|
4
|
+
require_relative "configuration"
|
|
5
|
+
|
|
6
|
+
module ActiveCachedResource
|
|
7
|
+
module Model
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
class << self
|
|
12
|
+
attr_accessor :cached_resource
|
|
13
|
+
|
|
14
|
+
def cached_resource(options = {})
|
|
15
|
+
@cached_resource || setup_cached_resource!(options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup_cached_resource!(options)
|
|
19
|
+
@cached_resource = ActiveCachedResource::Configuration.new(self, options)
|
|
20
|
+
include ActiveCachedResource::Caching
|
|
21
|
+
@cached_resource
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ClassMethods
|
|
27
|
+
def inherited(child)
|
|
28
|
+
child.cached_resource = cached_resource if defined?(@cached_resource)
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "activeresource/lib/activeresource"
|
|
4
|
+
|
|
5
|
+
require_relative "active_cached_resource/model"
|
|
6
|
+
require_relative "active_cached_resource/version"
|
|
7
|
+
|
|
8
|
+
module ActiveCachedResource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module ActiveResource
|
|
12
|
+
class Base
|
|
13
|
+
include ActiveCachedResource::Model
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Collection
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# Monkey patch ActiveResource::Collection to handle caching
|
|
20
|
+
# @see lib/activeresource/lib/active_resource/collection.rb
|
|
21
|
+
def request_resources!
|
|
22
|
+
return @elements if requested?
|
|
23
|
+
|
|
24
|
+
# MONKEY PATCH
|
|
25
|
+
# Delete the reload param from query params.
|
|
26
|
+
# This is drilled down via `params` option to determine if the collection should be reloaded
|
|
27
|
+
should_reload = query_params.delete(ActiveCachedResource::Caching::RELOAD_PARAM)
|
|
28
|
+
if !should_reload
|
|
29
|
+
from_cache = resource_class.send(:cache_read, from, path_params, query_params, prefix_options)
|
|
30
|
+
@elements = from_cache
|
|
31
|
+
return @elements if @elements
|
|
32
|
+
end
|
|
33
|
+
# MONKEY PATCH
|
|
34
|
+
|
|
35
|
+
response =
|
|
36
|
+
case from
|
|
37
|
+
when Symbol
|
|
38
|
+
resource_class.get(from, path_params)
|
|
39
|
+
when String
|
|
40
|
+
path = "#{from}#{query_string(query_params)}"
|
|
41
|
+
resource_class.format.decode(resource_class.connection.get(path, resource_class.headers).body)
|
|
42
|
+
else
|
|
43
|
+
path = resource_class.collection_path(prefix_options, query_params)
|
|
44
|
+
resource_class.format.decode(resource_class.connection.get(path, resource_class.headers).body)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Update the elements
|
|
48
|
+
parse_response(response)
|
|
49
|
+
@elements.map! { |e| resource_class.instantiate_record(e, prefix_options) }
|
|
50
|
+
|
|
51
|
+
# MONKEY PATCH
|
|
52
|
+
# Write cache
|
|
53
|
+
resource_class.send(:cache_write, @elements, from, path_params, query_params, prefix_options)
|
|
54
|
+
@elements
|
|
55
|
+
# MONKEY PATCH
|
|
56
|
+
rescue ActiveResource::ResourceNotFound
|
|
57
|
+
# Swallowing ResourceNotFound exceptions and return nothing - as per ActiveRecord.
|
|
58
|
+
# Needs to be empty array as Array methods are delegated
|
|
59
|
+
[]
|
|
60
|
+
ensure
|
|
61
|
+
@requested = true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Don't put *.swp, *.bak, etc here; those belong in a global ~/.gitignore.
|
|
2
|
+
# Check out http://help.github.com/ignore-files/ for how to set that up.
|
|
3
|
+
|
|
4
|
+
debug.log
|
|
5
|
+
.Gemfile
|
|
6
|
+
/.bundle
|
|
7
|
+
/.ruby-version
|
|
8
|
+
*.lock
|
|
9
|
+
/pkg
|
|
10
|
+
/dist
|
|
11
|
+
/doc/rdoc
|
|
12
|
+
/*/doc
|
|
13
|
+
/*/test/tmp
|
|
14
|
+
/RDOC_MAIN.rdoc
|
|
15
|
+
.rubocop-http*
|