static_association 0.0.2 → 0.2.0
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 +5 -5
- data/.github/workflows/lint.yml +15 -0
- data/.github/workflows/test.yml +24 -0
- data/.gitignore +3 -0
- data/.standard.yml +3 -0
- data/Appraisals +6 -12
- data/CHANGELOG.md +19 -0
- data/CODEOWNERS +16 -0
- data/Gemfile +1 -1
- data/README.md +41 -15
- data/Rakefile +4 -3
- data/gemfiles/{3.2.gemfile → 7.1.gemfile} +2 -2
- data/gemfiles/{4.0.gemfile → 7.2.gemfile} +2 -2
- data/gemfiles/{3.0.gemfile → 8.0.gemfile} +2 -3
- data/lib/static_association/version.rb +1 -1
- data/lib/static_association.rb +70 -24
- data/spec/spec_helper.rb +3 -7
- data/spec/static_association_spec.rb +376 -62
- data/static_association.gemspec +14 -16
- metadata +28 -49
- data/.travis.yml +0 -20
- data/gemfiles/3.0.gemfile.lock +0 -36
- data/gemfiles/3.1.gemfile +0 -8
- data/gemfiles/3.1.gemfile.lock +0 -38
- data/gemfiles/3.2.gemfile.lock +0 -38
- data/gemfiles/4.0.gemfile.lock +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 86ead7939a0117761cc96d89b8bead9dd9d6158e6266a8d068c9033b55fa727a
|
4
|
+
data.tar.gz: b8e8fed19948fa1c38dd7b975c083af75c1e232f89010d197ca661bb48c6a422
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a524a9345a9b43d5f6c9651e2be95cdc56095fca59a5cf7e97b032e424d122fe1769d365caed9c993ef01b49f6fa77cdcab23b1e841a731392ffe0ebd7707883
|
7
|
+
data.tar.gz: 5a54cf10f28c4582cd9aa9d353defc0c8fe853014be4c883563f7f7b6bbad0d856a0f5d889ec5ca8f16c04d1f1ebf56fc71506dfdd7d776e6c754bf8c74a5e02
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
ruby: ['3.2', '3.3', '3.4']
|
11
|
+
gemfile: ['7.1', '7.2', '8.0']
|
12
|
+
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
env:
|
16
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
- run: bundle exec rspec
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
data/Appraisals
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
appraise "
|
2
|
-
gem "
|
3
|
-
gem "activesupport", "3.0"
|
1
|
+
appraise "7.1" do
|
2
|
+
gem "activesupport", "7.1"
|
4
3
|
end
|
5
4
|
|
6
|
-
appraise "
|
7
|
-
gem "
|
8
|
-
gem "activesupport", "3.1"
|
5
|
+
appraise "7.2" do
|
6
|
+
gem "activesupport", "7.2"
|
9
7
|
end
|
10
8
|
|
11
|
-
appraise "
|
12
|
-
gem "activesupport", "
|
13
|
-
end
|
14
|
-
|
15
|
-
appraise "4.0" do
|
16
|
-
gem "activesupport", "4.0"
|
9
|
+
appraise "8.0" do
|
10
|
+
gem "activesupport", "8.0"
|
17
11
|
end
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## v0.2.0 (20 June 2025)
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- `standardrb` gem for linting (#11)
|
8
|
+
- `.where` method for finding multiple records with an array of IDs (#16)
|
9
|
+
- `.ids` method which returns an array of all record IDs (#25)
|
10
|
+
- `.find_by` method to return the first method matching a specific condition (#26)
|
11
|
+
- `.find_by!` method which behaves like `find_by` but raises when a matching
|
12
|
+
record is not found (#28)
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- Use GitHub Actions for CI (#10)
|
16
|
+
- Refactor specs to be more inline with thoughtbot style (#15)
|
17
|
+
- Require `activesupport` v7.1.0 or higher (#22)
|
18
|
+
- Coerce `.find_by_id` argument to integer (#23)
|
19
|
+
- More descriptive exception messages (#24)
|
data/CODEOWNERS
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Lines starting with '#' are comments.
|
2
|
+
# Each line is a file pattern followed by one or more owners.
|
3
|
+
|
4
|
+
# More details are here: https://help.github.com/articles/about-codeowners/
|
5
|
+
|
6
|
+
# The '*' pattern is global owners.
|
7
|
+
|
8
|
+
# Order is important. The last matching pattern has the most precedence.
|
9
|
+
# The folders are ordered as follows:
|
10
|
+
|
11
|
+
# In each subsection folders are ordered first by depth, then alphabetically.
|
12
|
+
# This should make it easy to add new rules without breaking existing ones.
|
13
|
+
|
14
|
+
# Global rule:
|
15
|
+
|
16
|
+
* @sidane
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
# StaticAssociation
|
2
2
|
|
3
|
-
|
3
|
+

|
4
|
+

|
4
5
|
|
5
|
-
|
6
|
+
Adds basic ActiveRecord-like associations to static data.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
10
|
Add this line to your application's Gemfile:
|
10
11
|
|
11
|
-
|
12
|
+
```ruby
|
13
|
+
gem "static_association"
|
14
|
+
```
|
12
15
|
|
13
16
|
And then execute:
|
14
17
|
|
@@ -24,25 +27,48 @@ Or install it yourself as:
|
|
24
27
|
|
25
28
|
Create your static association class:
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
```ruby
|
31
|
+
class Day
|
32
|
+
include StaticAssociation
|
29
33
|
|
30
|
-
|
34
|
+
attr_accessor :name
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
record id: 0 do |day|
|
37
|
+
day.name = :monday
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
36
41
|
|
37
|
-
Calling `record` will allow you to create an instance of this static model,
|
42
|
+
Calling `record` will allow you to create an instance of this static model,
|
43
|
+
a unique id is mandatory. The newly created object is yielded to the passed
|
44
|
+
block.
|
38
45
|
|
39
|
-
The `
|
46
|
+
The `Day` class will gain the following methods:
|
47
|
+
|
48
|
+
- `.all`: returns all the static records defined in the class.
|
49
|
+
- `.ids`: returns an array of all the ids of the static records.
|
50
|
+
- `.find`: accepts a single id and returns the matching record. If the record
|
51
|
+
does not exist, a `RecordNotFound` error is raised.
|
52
|
+
- `.find_by_id`: behaves similarly to the `.find` method, except it returns
|
53
|
+
`nil` when a record does not exist.
|
54
|
+
- `.find_by`: finds the first record matching the specified conditions. If no
|
55
|
+
record is found, returns `nil`.
|
56
|
+
- `find_by!` behaves like `find_by` but raises a
|
57
|
+
`StaticAssociation::RecordNotFound` error if no record is found.
|
58
|
+
- `.where`: accepts an array of ids and returns all records with matching ids.
|
40
59
|
|
41
60
|
### Associations
|
42
61
|
|
43
|
-
Currently just a
|
62
|
+
Currently just a `belongs_to` association can be created. This behaviour can be
|
63
|
+
mixed into an `ActiveRecord` model:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class Event < ActiveRecord::Base
|
67
|
+
extend StaticAssociation::AssociationHelpers
|
44
68
|
|
45
|
-
|
69
|
+
belongs_to_static :day
|
70
|
+
end
|
71
|
+
```
|
46
72
|
|
47
73
|
This assumes your model has a field `day_id`.
|
48
74
|
|
@@ -51,6 +77,6 @@ This assumes your model has a field `day_id`.
|
|
51
77
|
1. Fork it
|
52
78
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
79
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
54
|
-
4. Run
|
80
|
+
4. Run lint checks and tests (`bundle exec rake`)
|
55
81
|
5. Push to the branch (`git push origin my-new-feature`)
|
56
82
|
6. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "appraisal"
|
4
|
+
require "standard/rake"
|
4
5
|
|
5
6
|
RSpec::Core::RakeTask.new(:spec)
|
6
7
|
|
7
|
-
task :
|
8
|
+
task default: [:standard, :spec]
|
data/lib/static_association.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require 'active_support/core_ext/string/inflections'
|
1
|
+
require "static_association/version"
|
2
|
+
require "active_support/concern"
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
require "active_support/core_ext/hash/keys"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
7
6
|
|
8
7
|
module StaticAssociation
|
9
8
|
extend ActiveSupport::Concern
|
10
9
|
|
10
|
+
class ArgumentError < StandardError; end
|
11
|
+
|
11
12
|
class DuplicateID < StandardError; end
|
13
|
+
|
12
14
|
class RecordNotFound < StandardError; end
|
13
15
|
|
16
|
+
class UndefinedAttribute < StandardError; end
|
17
|
+
|
14
18
|
attr_reader :id
|
15
19
|
|
16
20
|
private
|
@@ -22,44 +26,86 @@ module StaticAssociation
|
|
22
26
|
module ClassMethods
|
23
27
|
include Enumerable
|
24
28
|
|
25
|
-
delegate :each, :
|
29
|
+
delegate :each, to: :all
|
26
30
|
|
27
31
|
def index
|
28
|
-
@index ||=
|
32
|
+
@index ||= {}
|
29
33
|
end
|
30
34
|
|
31
35
|
def all
|
32
36
|
index.values
|
33
37
|
end
|
34
38
|
|
39
|
+
def ids
|
40
|
+
index.keys
|
41
|
+
end
|
42
|
+
|
35
43
|
def find(id)
|
36
|
-
raise RecordNotFound
|
37
|
-
|
44
|
+
find_by_id(id) or raise RecordNotFound.new(
|
45
|
+
"Couldn't find DummyClass with 'id'=#{id}"
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_by_id(id)
|
50
|
+
index[
|
51
|
+
Integer(id, exception: false) || id
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
def where(id: [])
|
56
|
+
all.select { |record| id.include?(record.id) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_by(**args)
|
60
|
+
args.any? or raise ArgumentError
|
61
|
+
|
62
|
+
all.find { |record| matches_attributes?(record: record, attributes: args) }
|
38
63
|
end
|
39
64
|
|
40
|
-
def
|
65
|
+
def find_by!(**args)
|
66
|
+
find_by(**args) or raise RecordNotFound.new(
|
67
|
+
"Couldn't find #{name} with " +
|
68
|
+
args.map { |k, v| "#{k}=#{v}" }.join(", ")
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def record(settings, &block)
|
41
73
|
settings.assert_valid_keys(:id)
|
42
74
|
id = settings.fetch(:id)
|
43
|
-
|
44
|
-
|
45
|
-
|
75
|
+
|
76
|
+
if index.has_key?(id)
|
77
|
+
raise DuplicateID.new("Duplicate record with 'id'=#{id} found")
|
78
|
+
end
|
79
|
+
|
80
|
+
record = new(id)
|
81
|
+
record.instance_exec(record, &block) if block
|
46
82
|
index[id] = record
|
47
83
|
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def matches_attributes?(record:, attributes:)
|
88
|
+
attributes.all? do |attribute, value|
|
89
|
+
record.respond_to?(attribute) or raise UndefinedAttribute.new(
|
90
|
+
"Undefined attribute '#{attribute}'"
|
91
|
+
)
|
92
|
+
|
93
|
+
record.public_send(attribute) == value
|
94
|
+
end
|
95
|
+
end
|
48
96
|
end
|
49
97
|
|
50
98
|
module AssociationHelpers
|
51
|
-
def belongs_to_static(name)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
nil
|
58
|
-
end
|
99
|
+
def belongs_to_static(name, opts = {})
|
100
|
+
class_name = opts.fetch(:class_name, name.to_s.camelize)
|
101
|
+
|
102
|
+
send(:define_method, name) do
|
103
|
+
foreign_key = send(:"#{name}_id")
|
104
|
+
class_name.constantize.find_by_id(foreign_key)
|
59
105
|
end
|
60
106
|
|
61
|
-
|
62
|
-
|
107
|
+
send(:define_method, "#{name}=") do |assoc|
|
108
|
+
send(:"#{name}_id=", assoc.id)
|
63
109
|
end
|
64
110
|
end
|
65
111
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,14 +4,10 @@
|
|
4
4
|
# loaded once.
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
-
require
|
8
|
-
require 'bundler/setup'
|
7
|
+
require "bundler/setup"
|
9
8
|
|
10
|
-
require
|
9
|
+
require "static_association"
|
11
10
|
|
12
11
|
RSpec.configure do |config|
|
13
|
-
config.
|
14
|
-
config.run_all_when_everything_filtered = true
|
15
|
-
config.filter_run :focus
|
16
|
-
config.order = 'random'
|
12
|
+
config.order = "random"
|
17
13
|
end
|
@@ -1,105 +1,419 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "static_association"
|
3
3
|
|
4
|
-
|
4
|
+
class DummyClass
|
5
|
+
include StaticAssociation
|
6
|
+
attr_accessor :name
|
7
|
+
end
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
9
|
+
class AssociationClass
|
10
|
+
attr_accessor :dummy_class_id
|
11
|
+
attr_accessor :dodo_class_id
|
10
12
|
|
13
|
+
extend StaticAssociation::AssociationHelpers
|
14
|
+
belongs_to_static :dummy_class
|
15
|
+
belongs_to_static :dodo_class, class_name: "DummyClass"
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.describe StaticAssociation do
|
11
19
|
after do
|
12
|
-
DummyClass.instance_variable_set(
|
20
|
+
DummyClass.instance_variable_set(:@index, {})
|
13
21
|
end
|
14
22
|
|
15
23
|
describe ".record" do
|
16
|
-
it "
|
17
|
-
expect {
|
18
|
-
|
19
|
-
c.name = 'asdf'
|
20
|
-
end
|
21
|
-
}.to change(DummyClass, :count).by(1)
|
24
|
+
it "adds a record" do
|
25
|
+
expect { DummyClass.record(id: 1) { self.name = "test" } }
|
26
|
+
.to change(DummyClass, :count).by(1)
|
22
27
|
end
|
23
28
|
|
24
|
-
context "
|
25
|
-
it "
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
context "when using `self`" do
|
30
|
+
it "assigns attributes" do
|
31
|
+
record = DummyClass.record(id: 1) { self.name = "test" }
|
32
|
+
|
33
|
+
expect(record.id).to eq(1)
|
34
|
+
expect(record.name).to eq("test")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when using the object" do
|
39
|
+
it "assigns attributes" do
|
40
|
+
record = DummyClass.record(id: 1) { |i| i.name = "test" }
|
41
|
+
|
42
|
+
expect(record.id).to eq(1)
|
43
|
+
expect(record.name).to eq("test")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when the id is a duplicate" do
|
48
|
+
it "raises an error" do
|
49
|
+
DummyClass.record(id: 1) { self.name = "test0" }
|
50
|
+
|
51
|
+
expect { DummyClass.record(id: 1) { self.name = "test1" } }
|
52
|
+
.to raise_error(
|
53
|
+
StaticAssociation::DuplicateID,
|
54
|
+
"Duplicate record with 'id'=1 found"
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when an attribute is not defined" do
|
60
|
+
it "raises an error" do
|
61
|
+
expect { DummyClass.record(id: 1) { self.foo = "bar" } }
|
62
|
+
.to raise_error(NoMethodError)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when a key is invalid" do
|
67
|
+
it "raises an error" do
|
68
|
+
expect { DummyClass.record(id: 1, foo: "bar") }
|
69
|
+
.to raise_error(ArgumentError)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "without a block" do
|
74
|
+
it "adds a record" do
|
75
|
+
expect { DummyClass.record(id: 1) }.to change(DummyClass, :count).by(1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe ".all" do
|
81
|
+
it "returns all records" do
|
82
|
+
record1 = DummyClass.record(id: 1)
|
83
|
+
record2 = DummyClass.record(id: 2)
|
84
|
+
|
85
|
+
records = DummyClass.all
|
86
|
+
|
87
|
+
expect(records).to contain_exactly(record1, record2)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe ".ids" do
|
92
|
+
it "returns array of ids for all records" do
|
93
|
+
_record1 = DummyClass.record(id: 1)
|
94
|
+
_record2 = DummyClass.record(id: 2)
|
95
|
+
|
96
|
+
ids = DummyClass.ids
|
97
|
+
|
98
|
+
expect(ids).to contain_exactly(1, 2)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe ".find" do
|
103
|
+
context "when the record exists" do
|
104
|
+
it "returns the record" do
|
105
|
+
record = DummyClass.record(id: 1)
|
106
|
+
|
107
|
+
found_record = DummyClass.find(1)
|
108
|
+
|
109
|
+
expect(found_record).to eq(record)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when the record does not exist" do
|
114
|
+
it "raises an error" do
|
115
|
+
expect { DummyClass.find(1) }
|
116
|
+
.to raise_error(
|
117
|
+
StaticAssociation::RecordNotFound,
|
118
|
+
"Couldn't find DummyClass with 'id'=1"
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when argument is numeric string" do
|
124
|
+
it "returns the record" do
|
125
|
+
record = DummyClass.record(id: 1)
|
126
|
+
|
127
|
+
found_record = DummyClass.find("1")
|
128
|
+
|
129
|
+
expect(found_record).to eq(record)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe ".find_by_id" do
|
135
|
+
context "when the record exists" do
|
136
|
+
it "returns the record" do
|
137
|
+
record = DummyClass.record(id: 1)
|
138
|
+
|
139
|
+
found_record = DummyClass.find_by_id(1)
|
140
|
+
|
141
|
+
expect(found_record).to eq(record)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "when the record does not exist" do
|
146
|
+
it "returns nil" do
|
147
|
+
found_record = DummyClass.find_by_id(1)
|
148
|
+
|
149
|
+
expect(found_record).to be_nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when id argument is a numeric string" do
|
154
|
+
it "returns the record" do
|
155
|
+
record = DummyClass.record(id: 1)
|
156
|
+
|
157
|
+
found_record = DummyClass.find_by_id("1")
|
158
|
+
|
159
|
+
expect(found_record).to eq(record)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "when id argument is a non-numeric string" do
|
164
|
+
it "returns the record" do
|
165
|
+
DummyClass.record(id: 1)
|
166
|
+
|
167
|
+
found_record = DummyClass.find_by_id("foo")
|
168
|
+
|
169
|
+
expect(found_record).to be_nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when record ids are strings and id argument matches a record" do
|
174
|
+
it "returns the record" do
|
175
|
+
record = DummyClass.record(id: "foo")
|
176
|
+
|
177
|
+
found_record = DummyClass.find_by_id("foo")
|
178
|
+
|
179
|
+
expect(found_record).to eq(record)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when record ids are strings and id argument doesn't match a record" do
|
184
|
+
it "returns nil" do
|
185
|
+
DummyClass.record(id: "foo")
|
186
|
+
|
187
|
+
found_record = DummyClass.find_by_id("bar")
|
188
|
+
|
189
|
+
expect(found_record).to be_nil
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe ".where" do
|
195
|
+
it "returns all records with the given ids" do
|
196
|
+
record1 = DummyClass.record(id: 1)
|
197
|
+
_record2 = DummyClass.record(id: 2)
|
198
|
+
record3 = DummyClass.record(id: 3)
|
199
|
+
|
200
|
+
results = DummyClass.where(id: [1, 3, 4])
|
201
|
+
|
202
|
+
expect(results).to contain_exactly(record1, record3)
|
203
|
+
end
|
204
|
+
|
205
|
+
describe ".find_by" do
|
206
|
+
context "when record exists with the specified attribute value" do
|
207
|
+
it "returns the record" do
|
208
|
+
record1 = DummyClass.record(id: 1) do |r|
|
209
|
+
r.name = "foo"
|
29
210
|
end
|
211
|
+
_record2 = DummyClass.record(id: 2) do |r|
|
212
|
+
r.name = "bar"
|
213
|
+
end
|
214
|
+
|
215
|
+
found_record = DummyClass.find_by(name: "foo")
|
216
|
+
|
217
|
+
expect(found_record).to eq(record1)
|
218
|
+
end
|
219
|
+
end
|
30
220
|
|
31
|
-
|
32
|
-
|
221
|
+
context "when no record exists that matches the specified attribute value" do
|
222
|
+
it "returns nil" do
|
223
|
+
DummyClass.record(id: 1) do |r|
|
224
|
+
r.name = "foo"
|
33
225
|
end
|
34
|
-
|
226
|
+
|
227
|
+
found_record = DummyClass.find_by(name: "bar")
|
228
|
+
|
229
|
+
expect(found_record).to be_nil
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context "when multiple records match the specified attribute value" do
|
234
|
+
it "returns the first matching record" do
|
235
|
+
record1 = DummyClass.record(id: 1) do |r|
|
236
|
+
r.name = "foo"
|
237
|
+
end
|
238
|
+
_record2 = DummyClass.record(id: 2) do |r|
|
239
|
+
r.name = "foo"
|
240
|
+
end
|
241
|
+
|
242
|
+
found_record = DummyClass.find_by(name: "foo")
|
243
|
+
|
244
|
+
expect(found_record).to eq(record1)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "when specifying multiple attribute values" do
|
249
|
+
it "returns the record matching all attributes" do
|
250
|
+
_record1 = DummyClass.record(id: 1) do |r|
|
251
|
+
r.name = "foo"
|
252
|
+
end
|
253
|
+
record2 = DummyClass.record(id: 2) do |r|
|
254
|
+
r.name = "foo"
|
255
|
+
end
|
256
|
+
|
257
|
+
found_record = DummyClass.find_by(id: 2, name: "foo")
|
258
|
+
|
259
|
+
expect(found_record).to eq(record2)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context "when specifying multiple attribute values but no record " \
|
264
|
+
"matches all attributes" do
|
265
|
+
it "returns nil" do
|
266
|
+
_record1 = DummyClass.record(id: 1) do |r|
|
267
|
+
r.name = "foo"
|
268
|
+
end
|
269
|
+
|
270
|
+
found_record = DummyClass.find_by(id: 1, name: "bar")
|
271
|
+
|
272
|
+
expect(found_record).to be_nil
|
273
|
+
end
|
35
274
|
end
|
36
|
-
end
|
37
275
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
276
|
+
context "with undefined attributes" do
|
277
|
+
it "raises an error" do
|
278
|
+
DummyClass.record(id: 1)
|
279
|
+
|
280
|
+
expect {
|
281
|
+
DummyClass.find_by(undefined_attribute: 1)
|
282
|
+
}.to raise_error(
|
283
|
+
StaticAssociation::UndefinedAttribute,
|
284
|
+
"Undefined attribute 'undefined_attribute'"
|
285
|
+
)
|
42
286
|
end
|
43
|
-
|
287
|
+
end
|
44
288
|
|
45
|
-
|
46
|
-
|
289
|
+
context "with no attributes" do
|
290
|
+
it "raises a StaticAssociation::ArgumentError" do
|
291
|
+
expect {
|
292
|
+
DummyClass.find_by
|
293
|
+
}.to raise_error(StaticAssociation::ArgumentError)
|
294
|
+
end
|
295
|
+
end
|
47
296
|
end
|
297
|
+
end
|
48
298
|
|
49
|
-
|
50
|
-
|
299
|
+
describe ".find_by!" do
|
300
|
+
context "when record exists with the specified attribute value" do
|
301
|
+
it "returns the record" do
|
302
|
+
record1 = DummyClass.record(id: 1) do |r|
|
303
|
+
r.name = "foo"
|
304
|
+
end
|
305
|
+
_record2 = DummyClass.record(id: 2) do |r|
|
306
|
+
r.name = "bar"
|
307
|
+
end
|
51
308
|
|
52
|
-
|
53
|
-
|
309
|
+
found_record = DummyClass.find_by!(name: "foo")
|
310
|
+
|
311
|
+
expect(found_record).to eq(record1)
|
312
|
+
end
|
54
313
|
end
|
55
314
|
|
56
|
-
context "
|
57
|
-
it "
|
315
|
+
context "when no record exists that matches the specified attribute value" do
|
316
|
+
it "raises an error" do
|
317
|
+
DummyClass.record(id: 1) do |r|
|
318
|
+
r.name = "foo"
|
319
|
+
end
|
320
|
+
|
58
321
|
expect {
|
59
|
-
DummyClass.
|
60
|
-
}.to raise_error(
|
322
|
+
DummyClass.find_by!(name: "bar")
|
323
|
+
}.to raise_error(
|
324
|
+
StaticAssociation::RecordNotFound,
|
325
|
+
"Couldn't find DummyClass with name=bar"
|
326
|
+
)
|
61
327
|
end
|
62
328
|
end
|
63
|
-
end
|
64
329
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
330
|
+
context "when multiple records match the specified attribute value" do
|
331
|
+
it "returns the first matching record" do
|
332
|
+
record1 = DummyClass.record(id: 1) do |r|
|
333
|
+
r.name = "foo"
|
334
|
+
end
|
335
|
+
_record2 = DummyClass.record(id: 2) do |r|
|
336
|
+
r.name = "foo"
|
337
|
+
end
|
338
|
+
|
339
|
+
found_record = DummyClass.find_by!(name: "foo")
|
340
|
+
|
341
|
+
expect(found_record).to eq(record1)
|
69
342
|
end
|
70
343
|
end
|
71
344
|
|
72
|
-
context "
|
73
|
-
|
345
|
+
context "when specifying multiple attribute values" do
|
346
|
+
it "returns the record matching all attributes" do
|
347
|
+
_record1 = DummyClass.record(id: 1) do |r|
|
348
|
+
r.name = "foo"
|
349
|
+
end
|
350
|
+
record2 = DummyClass.record(id: 2) do |r|
|
351
|
+
r.name = "foo"
|
352
|
+
end
|
74
353
|
|
75
|
-
|
76
|
-
|
354
|
+
found_record = DummyClass.find_by!(id: 2, name: "foo")
|
355
|
+
|
356
|
+
expect(found_record).to eq(record2)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context "when specifying multiple attribute values but no record " \
|
361
|
+
"matches all attributes" do
|
362
|
+
it "raises an error" do
|
363
|
+
_record1 = DummyClass.record(id: 1) do |r|
|
364
|
+
r.name = "foo"
|
365
|
+
end
|
366
|
+
|
367
|
+
expect {
|
368
|
+
DummyClass.find_by!(id: 1, name: "bar")
|
369
|
+
}.to raise_error(
|
370
|
+
StaticAssociation::RecordNotFound,
|
371
|
+
"Couldn't find DummyClass with id=1, name=bar"
|
372
|
+
)
|
373
|
+
end
|
77
374
|
end
|
78
375
|
|
79
|
-
context "
|
80
|
-
it "
|
376
|
+
context "with undefined attributes" do
|
377
|
+
it "raises a StaticAssociation::UndefinedAttribute" do
|
378
|
+
DummyClass.record(id: 1)
|
379
|
+
|
81
380
|
expect {
|
82
|
-
DummyClass.
|
83
|
-
}.to raise_error(
|
381
|
+
DummyClass.find_by!(undefined_attribute: 1)
|
382
|
+
}.to raise_error(
|
383
|
+
StaticAssociation::UndefinedAttribute,
|
384
|
+
"Undefined attribute 'undefined_attribute'"
|
385
|
+
)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context "with no attributes" do
|
390
|
+
it "raises a StaticAssociation::ArgumentError" do
|
391
|
+
expect {
|
392
|
+
DummyClass.find_by!
|
393
|
+
}.to raise_error(StaticAssociation::ArgumentError)
|
84
394
|
end
|
85
395
|
end
|
86
396
|
end
|
87
397
|
|
88
398
|
describe ".belongs_to_static" do
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
399
|
+
it "defines a reader method for the association" do
|
400
|
+
associated_class = AssociationClass.new
|
401
|
+
allow(DummyClass).to receive(:find_by_id)
|
402
|
+
|
403
|
+
associated_class.dummy_class
|
404
|
+
|
405
|
+
expect(DummyClass).to have_received(:find_by_id)
|
94
406
|
end
|
95
407
|
|
96
|
-
|
408
|
+
context "when `class_name` is specified" do
|
409
|
+
it "defines a reader method for the association" do
|
410
|
+
associated_class = AssociationClass.new
|
411
|
+
allow(DummyClass).to receive(:find_by_id)
|
97
412
|
|
98
|
-
|
99
|
-
|
100
|
-
DummyClass.
|
101
|
-
|
102
|
-
associated_class.dummy_class
|
413
|
+
associated_class.dodo_class
|
414
|
+
|
415
|
+
expect(DummyClass).to have_received(:find_by_id)
|
416
|
+
end
|
103
417
|
end
|
104
418
|
end
|
105
419
|
end
|
data/static_association.gemspec
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "static_association/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.description
|
12
|
-
spec.summary
|
13
|
-
spec.license
|
6
|
+
spec.name = "static_association"
|
7
|
+
spec.version = StaticAssociation::VERSION
|
8
|
+
spec.authors = ["Oliver Nightingale"]
|
9
|
+
spec.email = ["oliver.nightingale1@gmail.com"]
|
10
|
+
spec.description = "StaticAssociation adds a simple enum type that can act like an ActiveRecord association for static data."
|
11
|
+
spec.summary = "ActiveRecord like associations for static data"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.homepage = "https://github.com/thoughtbot/static_association"
|
14
14
|
|
15
|
-
spec.files
|
16
|
-
spec.executables
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.require_paths = ["lib"]
|
19
18
|
|
20
|
-
spec.add_dependency "activesupport", ">=
|
19
|
+
spec.add_dependency "activesupport", ">= 7.1.0"
|
21
20
|
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
23
21
|
spec.add_development_dependency "rspec"
|
24
|
-
spec.add_development_dependency "rake"
|
25
22
|
spec.add_development_dependency "appraisal"
|
23
|
+
spec.add_development_dependency "standard"
|
26
24
|
end
|
metadata
CHANGED
@@ -1,83 +1,68 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: static_association
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oliver Nightingale
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
|
-
- -
|
16
|
+
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
18
|
+
version: 7.1.0
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
|
-
- -
|
23
|
+
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.3'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.3'
|
25
|
+
version: 7.1.0
|
41
26
|
- !ruby/object:Gem::Dependency
|
42
27
|
name: rspec
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
44
29
|
requirements:
|
45
|
-
- -
|
30
|
+
- - ">="
|
46
31
|
- !ruby/object:Gem::Version
|
47
32
|
version: '0'
|
48
33
|
type: :development
|
49
34
|
prerelease: false
|
50
35
|
version_requirements: !ruby/object:Gem::Requirement
|
51
36
|
requirements:
|
52
|
-
- -
|
37
|
+
- - ">="
|
53
38
|
- !ruby/object:Gem::Version
|
54
39
|
version: '0'
|
55
40
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
41
|
+
name: appraisal
|
57
42
|
requirement: !ruby/object:Gem::Requirement
|
58
43
|
requirements:
|
59
|
-
- -
|
44
|
+
- - ">="
|
60
45
|
- !ruby/object:Gem::Version
|
61
46
|
version: '0'
|
62
47
|
type: :development
|
63
48
|
prerelease: false
|
64
49
|
version_requirements: !ruby/object:Gem::Requirement
|
65
50
|
requirements:
|
66
|
-
- -
|
51
|
+
- - ">="
|
67
52
|
- !ruby/object:Gem::Version
|
68
53
|
version: '0'
|
69
54
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
55
|
+
name: standard
|
71
56
|
requirement: !ruby/object:Gem::Requirement
|
72
57
|
requirements:
|
73
|
-
- -
|
58
|
+
- - ">="
|
74
59
|
- !ruby/object:Gem::Version
|
75
60
|
version: '0'
|
76
61
|
type: :development
|
77
62
|
prerelease: false
|
78
63
|
version_requirements: !ruby/object:Gem::Requirement
|
79
64
|
requirements:
|
80
|
-
- -
|
65
|
+
- - ">="
|
81
66
|
- !ruby/object:Gem::Version
|
82
67
|
version: '0'
|
83
68
|
description: StaticAssociation adds a simple enum type that can act like an ActiveRecord
|
@@ -88,50 +73,44 @@ executables: []
|
|
88
73
|
extensions: []
|
89
74
|
extra_rdoc_files: []
|
90
75
|
files:
|
91
|
-
- .
|
92
|
-
- .
|
76
|
+
- ".github/workflows/lint.yml"
|
77
|
+
- ".github/workflows/test.yml"
|
78
|
+
- ".gitignore"
|
79
|
+
- ".standard.yml"
|
93
80
|
- Appraisals
|
81
|
+
- CHANGELOG.md
|
82
|
+
- CODEOWNERS
|
94
83
|
- Gemfile
|
95
84
|
- LICENSE.txt
|
96
85
|
- README.md
|
97
86
|
- Rakefile
|
98
|
-
- gemfiles/
|
99
|
-
- gemfiles/
|
100
|
-
- gemfiles/
|
101
|
-
- gemfiles/3.1.gemfile.lock
|
102
|
-
- gemfiles/3.2.gemfile
|
103
|
-
- gemfiles/3.2.gemfile.lock
|
104
|
-
- gemfiles/4.0.gemfile
|
105
|
-
- gemfiles/4.0.gemfile.lock
|
87
|
+
- gemfiles/7.1.gemfile
|
88
|
+
- gemfiles/7.2.gemfile
|
89
|
+
- gemfiles/8.0.gemfile
|
106
90
|
- lib/static_association.rb
|
107
91
|
- lib/static_association/version.rb
|
108
92
|
- spec/spec_helper.rb
|
109
93
|
- spec/static_association_spec.rb
|
110
94
|
- static_association.gemspec
|
111
|
-
homepage:
|
95
|
+
homepage: https://github.com/thoughtbot/static_association
|
112
96
|
licenses:
|
113
97
|
- MIT
|
114
98
|
metadata: {}
|
115
|
-
post_install_message:
|
116
99
|
rdoc_options: []
|
117
100
|
require_paths:
|
118
101
|
- lib
|
119
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
103
|
requirements:
|
121
|
-
- -
|
104
|
+
- - ">="
|
122
105
|
- !ruby/object:Gem::Version
|
123
106
|
version: '0'
|
124
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
108
|
requirements:
|
126
|
-
- -
|
109
|
+
- - ">="
|
127
110
|
- !ruby/object:Gem::Version
|
128
111
|
version: '0'
|
129
112
|
requirements: []
|
130
|
-
|
131
|
-
rubygems_version: 2.0.3
|
132
|
-
signing_key:
|
113
|
+
rubygems_version: 3.6.9
|
133
114
|
specification_version: 4
|
134
115
|
summary: ActiveRecord like associations for static data
|
135
|
-
test_files:
|
136
|
-
- spec/spec_helper.rb
|
137
|
-
- spec/static_association_spec.rb
|
116
|
+
test_files: []
|
data/.travis.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
install: bundle install
|
3
|
-
script:
|
4
|
-
- bundle exec rake
|
5
|
-
rvm:
|
6
|
-
- 2.0.0
|
7
|
-
- 1.9.3
|
8
|
-
- 1.9.2
|
9
|
-
- 1.8.7
|
10
|
-
gemfile:
|
11
|
-
- gemfiles/3.0.gemfile
|
12
|
-
- gemfiles/3.1.gemfile
|
13
|
-
- gemfiles/3.2.gemfile
|
14
|
-
- gemfiles/4.0.gemfile
|
15
|
-
matrix:
|
16
|
-
exclude:
|
17
|
-
- rvm: 1.8.7
|
18
|
-
gemfile: gemfiles/4.0.gemfile
|
19
|
-
- rvm: 1.9.2
|
20
|
-
gemfile: gemfiles/4.0.gemfile
|
data/gemfiles/3.0.gemfile.lock
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/olivernightingale/code/static_association
|
3
|
-
specs:
|
4
|
-
static_association (0.0.1)
|
5
|
-
activesupport (>= 3.0.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
activesupport (3.0.0)
|
11
|
-
appraisal (0.5.2)
|
12
|
-
bundler
|
13
|
-
rake
|
14
|
-
diff-lcs (1.2.4)
|
15
|
-
i18n (0.6.5)
|
16
|
-
rake (10.1.0)
|
17
|
-
rspec (2.14.1)
|
18
|
-
rspec-core (~> 2.14.0)
|
19
|
-
rspec-expectations (~> 2.14.0)
|
20
|
-
rspec-mocks (~> 2.14.0)
|
21
|
-
rspec-core (2.14.5)
|
22
|
-
rspec-expectations (2.14.3)
|
23
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
24
|
-
rspec-mocks (2.14.3)
|
25
|
-
|
26
|
-
PLATFORMS
|
27
|
-
ruby
|
28
|
-
|
29
|
-
DEPENDENCIES
|
30
|
-
activesupport (= 3.0)
|
31
|
-
appraisal
|
32
|
-
bundler (~> 1.3)
|
33
|
-
i18n
|
34
|
-
rake
|
35
|
-
rspec
|
36
|
-
static_association!
|
data/gemfiles/3.1.gemfile
DELETED
data/gemfiles/3.1.gemfile.lock
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/olivernightingale/code/static_association
|
3
|
-
specs:
|
4
|
-
static_association (0.0.1)
|
5
|
-
activesupport (>= 3.0.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
activesupport (3.1.0)
|
11
|
-
multi_json (~> 1.0)
|
12
|
-
appraisal (0.5.2)
|
13
|
-
bundler
|
14
|
-
rake
|
15
|
-
diff-lcs (1.2.4)
|
16
|
-
i18n (0.6.5)
|
17
|
-
multi_json (1.8.0)
|
18
|
-
rake (10.1.0)
|
19
|
-
rspec (2.14.1)
|
20
|
-
rspec-core (~> 2.14.0)
|
21
|
-
rspec-expectations (~> 2.14.0)
|
22
|
-
rspec-mocks (~> 2.14.0)
|
23
|
-
rspec-core (2.14.5)
|
24
|
-
rspec-expectations (2.14.3)
|
25
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
26
|
-
rspec-mocks (2.14.3)
|
27
|
-
|
28
|
-
PLATFORMS
|
29
|
-
ruby
|
30
|
-
|
31
|
-
DEPENDENCIES
|
32
|
-
activesupport (= 3.1)
|
33
|
-
appraisal
|
34
|
-
bundler (~> 1.3)
|
35
|
-
i18n
|
36
|
-
rake
|
37
|
-
rspec
|
38
|
-
static_association!
|
data/gemfiles/3.2.gemfile.lock
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/olivernightingale/code/static_association
|
3
|
-
specs:
|
4
|
-
static_association (0.0.1)
|
5
|
-
activesupport (>= 3.0.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
activesupport (3.2.0)
|
11
|
-
i18n (~> 0.6)
|
12
|
-
multi_json (~> 1.0)
|
13
|
-
appraisal (0.5.2)
|
14
|
-
bundler
|
15
|
-
rake
|
16
|
-
diff-lcs (1.2.4)
|
17
|
-
i18n (0.6.5)
|
18
|
-
multi_json (1.8.0)
|
19
|
-
rake (10.1.0)
|
20
|
-
rspec (2.14.1)
|
21
|
-
rspec-core (~> 2.14.0)
|
22
|
-
rspec-expectations (~> 2.14.0)
|
23
|
-
rspec-mocks (~> 2.14.0)
|
24
|
-
rspec-core (2.14.5)
|
25
|
-
rspec-expectations (2.14.3)
|
26
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
27
|
-
rspec-mocks (2.14.3)
|
28
|
-
|
29
|
-
PLATFORMS
|
30
|
-
ruby
|
31
|
-
|
32
|
-
DEPENDENCIES
|
33
|
-
activesupport (= 3.2)
|
34
|
-
appraisal
|
35
|
-
bundler (~> 1.3)
|
36
|
-
rake
|
37
|
-
rspec
|
38
|
-
static_association!
|
data/gemfiles/4.0.gemfile.lock
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/olivernightingale/code/static_association
|
3
|
-
specs:
|
4
|
-
static_association (0.0.1)
|
5
|
-
activesupport (>= 3.0.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
activesupport (4.0.0)
|
11
|
-
i18n (~> 0.6, >= 0.6.4)
|
12
|
-
minitest (~> 4.2)
|
13
|
-
multi_json (~> 1.3)
|
14
|
-
thread_safe (~> 0.1)
|
15
|
-
tzinfo (~> 0.3.37)
|
16
|
-
appraisal (0.5.2)
|
17
|
-
bundler
|
18
|
-
rake
|
19
|
-
atomic (1.1.13)
|
20
|
-
diff-lcs (1.2.4)
|
21
|
-
i18n (0.6.5)
|
22
|
-
minitest (4.7.5)
|
23
|
-
multi_json (1.8.0)
|
24
|
-
rake (10.1.0)
|
25
|
-
rspec (2.14.1)
|
26
|
-
rspec-core (~> 2.14.0)
|
27
|
-
rspec-expectations (~> 2.14.0)
|
28
|
-
rspec-mocks (~> 2.14.0)
|
29
|
-
rspec-core (2.14.5)
|
30
|
-
rspec-expectations (2.14.3)
|
31
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
32
|
-
rspec-mocks (2.14.3)
|
33
|
-
thread_safe (0.1.2)
|
34
|
-
atomic
|
35
|
-
tzinfo (0.3.37)
|
36
|
-
|
37
|
-
PLATFORMS
|
38
|
-
ruby
|
39
|
-
|
40
|
-
DEPENDENCIES
|
41
|
-
activesupport (= 4.0)
|
42
|
-
appraisal
|
43
|
-
bundler (~> 1.3)
|
44
|
-
rake
|
45
|
-
rspec
|
46
|
-
static_association!
|