arkenstone-open 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/codacy-analysis.yml +46 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +5 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +101 -0
- data/LICENSE.txt +11 -0
- data/README.md +87 -0
- data/Rakefile +36 -0
- data/arkenstone.gemspec +27 -0
- data/lib/arkenstone/associations/resources.rb +76 -0
- data/lib/arkenstone/associations.rb +389 -0
- data/lib/arkenstone/document.rb +289 -0
- data/lib/arkenstone/enumerable/query_list.rb +20 -0
- data/lib/arkenstone/errors/no_url_error.rb +14 -0
- data/lib/arkenstone/helpers.rb +18 -0
- data/lib/arkenstone/network/env.rb +19 -0
- data/lib/arkenstone/network/hook.rb +74 -0
- data/lib/arkenstone/network/network.rb +72 -0
- data/lib/arkenstone/query_builder.rb +84 -0
- data/lib/arkenstone/queryable.rb +38 -0
- data/lib/arkenstone/timestamps.rb +25 -0
- data/lib/arkenstone/validation/validation_error.rb +34 -0
- data/lib/arkenstone/validation/validations.rb +192 -0
- data/lib/arkenstone/version.rb +5 -0
- data/lib/arkenstone.rb +22 -0
- data/test/associations/test_document_overrides.rb +50 -0
- data/test/associations/test_has_and_belongs_to_many.rb +80 -0
- data/test/dummy/app/models/association.rb +35 -0
- data/test/dummy/app/models/superuser.rb +8 -0
- data/test/dummy/app/models/user.rb +10 -0
- data/test/spec_helper.rb +16 -0
- data/test/test_arkenstone.rb +354 -0
- data/test/test_arkenstone_hook_inheritance.rb +39 -0
- data/test/test_associations.rb +327 -0
- data/test/test_enumerables.rb +36 -0
- data/test/test_environment.rb +14 -0
- data/test/test_helpers.rb +18 -0
- data/test/test_hooks.rb +104 -0
- data/test/test_query_builder.rb +163 -0
- data/test/test_queryable.rb +59 -0
- data/test/test_validations.rb +197 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8d733a53e57cd9f59167299cedd91ee37b83060f62a18afeaf8d79d9b3b4184a
|
4
|
+
data.tar.gz: 9d68710e72885419899b52471cdd8cc09e9725bbe940f56a17e500d6207f7b45
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db74e65147e8d87b57a6a90cde59eca88651a87882846eecf04d038777fa69c1b76bf07d84757c77e3d32b5b81a0b66875a831d41d1809f5f568d758306cb38e
|
7
|
+
data.tar.gz: 756ae9b10fce7f54d5487e8215a82ef186318f720977af6488041a18235cc3ec53b09767871f981ed5f7b2a88bfe468a54913b69a4f6adfe8ed06ca817715c64
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This workflow checks out code, performs a Codacy security scan
|
2
|
+
# and integrates the results with the
|
3
|
+
# GitHub Advanced Security code scanning feature. For more information on
|
4
|
+
# the Codacy security scan action usage and parameters, see
|
5
|
+
# https://github.com/codacy/codacy-analysis-cli-action.
|
6
|
+
# For more information on Codacy Analysis CLI in general, see
|
7
|
+
# https://github.com/codacy/codacy-analysis-cli.
|
8
|
+
|
9
|
+
name: Codacy Security Scan
|
10
|
+
|
11
|
+
on:
|
12
|
+
push:
|
13
|
+
branches: ["development", "main"]
|
14
|
+
pull_request:
|
15
|
+
branches: ["development", "main"]
|
16
|
+
|
17
|
+
jobs:
|
18
|
+
codacy-security-scan:
|
19
|
+
name: Codacy Security Scan
|
20
|
+
runs-on: ubuntu-latest
|
21
|
+
steps:
|
22
|
+
# Checkout the repository to the GitHub Actions runner
|
23
|
+
- name: Checkout code
|
24
|
+
uses: actions/checkout@v2
|
25
|
+
|
26
|
+
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
27
|
+
- name: Run Codacy Analysis CLI
|
28
|
+
uses: codacy/codacy-analysis-cli-action@1.1.0
|
29
|
+
with:
|
30
|
+
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
31
|
+
# You can also omit the token and run the tools that support default configurations
|
32
|
+
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
33
|
+
verbose: true
|
34
|
+
output: results.sarif
|
35
|
+
format: sarif
|
36
|
+
# Adjust severity of non-security issues
|
37
|
+
gh-code-scanning-compat: true
|
38
|
+
# Force 0 exit code to allow SARIF file generation
|
39
|
+
# This will handover control about PR rejection to the GitHub side
|
40
|
+
max-allowed-issues: 2147483647
|
41
|
+
|
42
|
+
# Upload the SARIF file generated in the previous step
|
43
|
+
- name: Upload SARIF results file
|
44
|
+
uses: github/codeql-action/upload-sarif@v1
|
45
|
+
with:
|
46
|
+
sarif_file: results.sarif
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.1.2
|
data/.travis.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
dist: focal
|
2
|
+
env:
|
3
|
+
global:
|
4
|
+
- CC_TEST_REPORTER_ID=8d9ccf963273f583d380d4e2b97da731c25d77bb4784151ea4a6ec27bbbdaf22
|
5
|
+
language: ruby
|
6
|
+
rvm:
|
7
|
+
- 3.0.2
|
8
|
+
branches:
|
9
|
+
except:
|
10
|
+
- documentation
|
11
|
+
before_script:
|
12
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
|
+
- chmod +x ./cc-test-reporter
|
14
|
+
- ./cc-test-reporter before-build
|
15
|
+
after_script:
|
16
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
gem 'minitest'
|
7
|
+
gem 'pry'
|
8
|
+
gem 'pry-nav'
|
9
|
+
gem 'simplecov', require: false
|
10
|
+
gem 'test-unit' # test-unit was removed from ruby in version 2.2.0
|
11
|
+
gem 'webmock', '~> 3.9.3'
|
12
|
+
end
|
13
|
+
|
14
|
+
group :development do
|
15
|
+
gem 'flog'
|
16
|
+
gem 'rubocop'
|
17
|
+
gem 'yard'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Specify your gem's dependencies in arkenstone.gemspec
|
21
|
+
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
arkenstone (3.0.0)
|
5
|
+
activesupport (>= 5.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activesupport (7.0.4.3)
|
11
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
|
+
i18n (>= 1.6, < 2)
|
13
|
+
minitest (>= 5.1)
|
14
|
+
tzinfo (~> 2.0)
|
15
|
+
addressable (2.8.1)
|
16
|
+
public_suffix (>= 2.0.2, < 6.0)
|
17
|
+
ast (2.4.2)
|
18
|
+
coderay (1.1.3)
|
19
|
+
concurrent-ruby (1.2.2)
|
20
|
+
crack (0.4.5)
|
21
|
+
rexml
|
22
|
+
docile (1.4.0)
|
23
|
+
flog (4.6.6)
|
24
|
+
path_expander (~> 1.0)
|
25
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
26
|
+
sexp_processor (~> 4.8)
|
27
|
+
hashdiff (1.0.1)
|
28
|
+
i18n (1.12.0)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
json (2.6.3)
|
31
|
+
method_source (1.0.0)
|
32
|
+
minitest (5.18.0)
|
33
|
+
parallel (1.22.1)
|
34
|
+
parser (3.2.1.1)
|
35
|
+
ast (~> 2.4.1)
|
36
|
+
path_expander (1.1.1)
|
37
|
+
power_assert (2.0.3)
|
38
|
+
pry (0.14.2)
|
39
|
+
coderay (~> 1.1)
|
40
|
+
method_source (~> 1.0)
|
41
|
+
pry-nav (1.0.0)
|
42
|
+
pry (>= 0.9.10, < 0.15)
|
43
|
+
public_suffix (5.0.1)
|
44
|
+
rainbow (3.1.1)
|
45
|
+
rake (13.0.6)
|
46
|
+
regexp_parser (2.7.0)
|
47
|
+
rexml (3.2.5)
|
48
|
+
rubocop (1.48.1)
|
49
|
+
json (~> 2.3)
|
50
|
+
parallel (~> 1.10)
|
51
|
+
parser (>= 3.2.0.0)
|
52
|
+
rainbow (>= 2.2.2, < 4.0)
|
53
|
+
regexp_parser (>= 1.8, < 3.0)
|
54
|
+
rexml (>= 3.2.5, < 4.0)
|
55
|
+
rubocop-ast (>= 1.26.0, < 2.0)
|
56
|
+
ruby-progressbar (~> 1.7)
|
57
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
58
|
+
rubocop-ast (1.27.0)
|
59
|
+
parser (>= 3.2.1.0)
|
60
|
+
ruby-progressbar (1.13.0)
|
61
|
+
ruby_parser (3.20.0)
|
62
|
+
sexp_processor (~> 4.16)
|
63
|
+
sexp_processor (4.16.1)
|
64
|
+
simplecov (0.22.0)
|
65
|
+
docile (~> 1.1)
|
66
|
+
simplecov-html (~> 0.11)
|
67
|
+
simplecov_json_formatter (~> 0.1)
|
68
|
+
simplecov-html (0.12.3)
|
69
|
+
simplecov_json_formatter (0.1.4)
|
70
|
+
test-unit (3.5.7)
|
71
|
+
power_assert
|
72
|
+
tzinfo (2.0.6)
|
73
|
+
concurrent-ruby (~> 1.0)
|
74
|
+
unicode-display_width (2.4.2)
|
75
|
+
webmock (3.9.5)
|
76
|
+
addressable (>= 2.3.6)
|
77
|
+
crack (>= 0.3.2)
|
78
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
79
|
+
webrick (1.7.0)
|
80
|
+
yard (0.9.28)
|
81
|
+
webrick (~> 1.7.0)
|
82
|
+
|
83
|
+
PLATFORMS
|
84
|
+
ruby
|
85
|
+
|
86
|
+
DEPENDENCIES
|
87
|
+
arkenstone!
|
88
|
+
bundler (>= 2.1)
|
89
|
+
flog
|
90
|
+
minitest
|
91
|
+
pry
|
92
|
+
pry-nav
|
93
|
+
rake (>= 13.0.1)
|
94
|
+
rubocop
|
95
|
+
simplecov
|
96
|
+
test-unit
|
97
|
+
webmock (~> 3.9.3)
|
98
|
+
yard
|
99
|
+
|
100
|
+
BUNDLED WITH
|
101
|
+
2.2.22
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Arkenstone: a lightweight json active model like framework.
|
4
|
+
|
5
|
+
Copyright (C) 2020 Michael Christenson II
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Arkenstone [![Build Status](https://app.travis-ci.com/m3talsmith/arkenstone.svg?branch=development&status=passed)](https://app.travis-ci.com/m3talsmith/arkenstone) [![Maintainability](https://api.codeclimate.com/v1/badges/a0f3b07d272fcf220475/maintainability)](https://codeclimate.com/github/m3talsmith/arkenstone/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/a0f3b07d272fcf220475/test_coverage)](https://codeclimate.com/github/m3talsmith/arkenstone/test_coverage)
|
2
|
+
|
3
|
+
Arkenstone is a replacement for [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) that uses RESTful services to get and store data.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'arkenstone'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install arkenstone
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Include the `Arkenstone::Document` module in your class, set the `url` and `attributes` and away you go.
|
22
|
+
|
23
|
+
class User
|
24
|
+
include Arkenstone::Document
|
25
|
+
|
26
|
+
url 'http://example.com/users/'
|
27
|
+
attributes :name, :age, :gender
|
28
|
+
end
|
29
|
+
|
30
|
+
`User` instances will have accessor properties for `:name`, `:age`, and `:gender`. You can also `save`, and `update_attributes` as well:
|
31
|
+
|
32
|
+
my_user = User.create(name: 'Thorin', age: 195, gender: 'M', bearded: true)
|
33
|
+
|
34
|
+
This will make a `POST` to `http://example.com/users/`. If json data is returned from the server, it will be applied to the attributes of the object.
|
35
|
+
|
36
|
+
How about updating?
|
37
|
+
|
38
|
+
# Assuming Thorin has an id of 1
|
39
|
+
thorin = User.find(1)
|
40
|
+
|
41
|
+
# Thorin lost a bet and shaved... well you know how bets go!
|
42
|
+
thorin.update_attribute :bearded, false
|
43
|
+
|
44
|
+
This does a `PUT` to `http://example.com/users/1`. Again, returning json is translated back into a usable Thorin.
|
45
|
+
|
46
|
+
You can also change attributes using `#update_attributes` or setting them at a field level and saving.
|
47
|
+
|
48
|
+
# Thorin didn't shave for a day
|
49
|
+
thorin = User.find(1)
|
50
|
+
thorin.bearded = true
|
51
|
+
thorin.save
|
52
|
+
|
53
|
+
`Arkenstone` knows if you're a new object or not and properly uses `POST` or `PUT` where needed.
|
54
|
+
|
55
|
+
Here is a list of `RESTful` expectations that come with the library:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
Model.find(1) # => GET http://example.com/1
|
59
|
+
Model.all # => GET http://example.com
|
60
|
+
Model.new.save # => POST http://example.com
|
61
|
+
Model.find(1).save # => PUT http://example.com/1
|
62
|
+
Model.find(1).update_attribute(:attribute, 'value') # => PUT http://example.com/1
|
63
|
+
Model.find(1).update_attributes(attribute1: 'value1', attribute2: 'value2') # => PUT http://example.com/1
|
64
|
+
Model.find(1).destroy # => DELETE http://example.com/1
|
65
|
+
```
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
1. Fork it
|
70
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
72
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
5. Create new Pull Request
|
74
|
+
|
75
|
+
## License
|
76
|
+
|
77
|
+
The MIT License (MIT)
|
78
|
+
|
79
|
+
Arkenstone: a lightweight json active model like framework.
|
80
|
+
|
81
|
+
Copyright (C) 2020 Michael Christenson II
|
82
|
+
|
83
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
84
|
+
|
85
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
86
|
+
|
87
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if RUBY_VERSION.split('.')
|
4
|
+
.first.to_i < 3
|
5
|
+
abort 'Arkenstone development requires Ruby >= 3.0.2. ' \
|
6
|
+
'Please upgrade to a newer version of Ruby'
|
7
|
+
end
|
8
|
+
require 'rake/testtask'
|
9
|
+
require './lib/arkenstone/version'
|
10
|
+
|
11
|
+
task :build do
|
12
|
+
system 'gem build arkenstone.gemspec'
|
13
|
+
end
|
14
|
+
|
15
|
+
task package: :build do
|
16
|
+
system "gem push arkenstone-open-#{Arkenstone::VERSION}.gem"
|
17
|
+
end
|
18
|
+
|
19
|
+
task :analyze do
|
20
|
+
system 'rubocop -A'
|
21
|
+
system 'flog -g lib'
|
22
|
+
end
|
23
|
+
|
24
|
+
task :docs do
|
25
|
+
system 'yard doc'
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::TestTask.new do |t|
|
29
|
+
t.libs << 'test'
|
30
|
+
t.libs << 'test/test_associations'
|
31
|
+
t.verbose = false
|
32
|
+
t.warning = false
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Run tests'
|
36
|
+
task default: :test
|
data/arkenstone.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'arkenstone/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'arkenstone-open'
|
9
|
+
spec.version = Arkenstone::VERSION
|
10
|
+
spec.authors = ['Michael Christenson II', 'Steve Young', 'Scott Williams', 'Brett Byler']
|
11
|
+
spec.email = ['m3talsmith@gmail.com']
|
12
|
+
spec.description = 'An Open Source ActiveRecord replacement over REST'
|
13
|
+
spec.summary = 'A drop-in replacement for ActiveRecord that performs CRUD operations over RESTful URLs.'
|
14
|
+
spec.homepage = 'https://github.com/m3talsmith/arkenstone'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '>= 2.1'
|
22
|
+
spec.add_development_dependency 'rake', '>= 13.0.1'
|
23
|
+
spec.add_runtime_dependency 'activesupport', '>= 5.0'
|
24
|
+
|
25
|
+
spec.required_ruby_version = '>= 3.0'
|
26
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
27
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arkenstone
|
4
|
+
module Associations
|
5
|
+
module Resources
|
6
|
+
class << self
|
7
|
+
def included(base)
|
8
|
+
base.send :include, InstanceMethods
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
### Attaches singleton methods for has_many relationships
|
18
|
+
def attach_nested_has_many_resource_methods(nested_resources, nested_resource_name,
|
19
|
+
nested_resource_class_name = nested_resource_name)
|
20
|
+
parent_instance = self
|
21
|
+
parent_instance.extend HasManyParentSingletonMethods
|
22
|
+
parent_instance.add_resource_methods(nested_resource_name)
|
23
|
+
|
24
|
+
nested_klass = prefix_with_class_module(nested_resource_class_name.to_s.classify)
|
25
|
+
nested_klass = Kernel.const_get(nested_klass)
|
26
|
+
nested_klass.url build_nested_url(nested_resource_name)
|
27
|
+
|
28
|
+
nested_resources.define_singleton_method(:arkenstone_parent_instance) { parent_instance }
|
29
|
+
nested_resources.define_singleton_method(:arkenstone_nested_class) { nested_klass }
|
30
|
+
nested_resources.define_singleton_method(:arkenstone_nested_resource_name) { nested_resource_name }
|
31
|
+
nested_resources.extend HasManySingletonMethods
|
32
|
+
nested_resources
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module HasManyParentSingletonMethods
|
37
|
+
def add_resource_methods(nested_resource_name)
|
38
|
+
parent_instance = self
|
39
|
+
resource_name_pluralized = nested_resource_name.to_s.pluralize
|
40
|
+
|
41
|
+
parent_instance.define_singleton_method "#{resource_name_pluralized}=" do |resources|
|
42
|
+
resources.each do |resource|
|
43
|
+
resource.send "#{parent_instance.class.to_s.demodulize.downcase}_id=", parent_instance.id
|
44
|
+
end
|
45
|
+
|
46
|
+
parent_instance.arkenstone_data[resource_name_pluralized.to_sym] = resources
|
47
|
+
resources
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module HasManySingletonMethods
|
53
|
+
def <<(resource)
|
54
|
+
push resource
|
55
|
+
arkenstone_parent_instance.send "#{arkenstone_nested_resource_name}=", self
|
56
|
+
end
|
57
|
+
|
58
|
+
def build(options)
|
59
|
+
parent_id = "#{arkenstone_parent_instance.class.to_s.demodulize.underscore}_id"
|
60
|
+
new_resource = arkenstone_nested_class.build(options.merge({ parent_id => arkenstone_parent_instance.id }))
|
61
|
+
parent_resource_instances = arkenstone_parent_instance.send arkenstone_nested_resource_name.to_sym
|
62
|
+
|
63
|
+
parent_resource_instances << new_resource
|
64
|
+
arkenstone_parent_instance.send "#{arkenstone_nested_resource_name}=", parent_resource_instances
|
65
|
+
|
66
|
+
new_resource
|
67
|
+
end
|
68
|
+
|
69
|
+
def create(options)
|
70
|
+
new_resource = build(options)
|
71
|
+
new_resource.save
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|