yml_record 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc9a3a6378dcf9c0065cd690c970165e47b0366109bf3f5630ccc7a3edfa6589
4
- data.tar.gz: 4e5f4eee77f815ce2d35e44d832dbe3fa73509650da6d0001d72d663ca58ade6
3
+ metadata.gz: a720c25b1835ff9e469ebe1f5d5f962d22d19f6ddfbe08bcf0f429d9634031dc
4
+ data.tar.gz: 29f1ebd2b3efa494e1961baba348438ef8e5616b255ae5bf5b033de2229f4a5f
5
5
  SHA512:
6
- metadata.gz: ab80c24471394a090dd7d899ce6322a99ac0176ce8925ccab7cd5c82a3b0f1e3c7783b91fa9c77476e50b61183e8e509bfdb7c9363d149971a04832bbb7d3398
7
- data.tar.gz: 21b4426dbceec8a10fa1de4b4b9d5e26a80b9692990ba0985ec46d4df70ff3f7a7fb14d1317e88fcb0c53e0fe709086827cb1f9ab47e1e235546b4f2287bb82c
6
+ metadata.gz: abef6d9f6097fadbb11dfb6342fcfab8f41516d09290a27bd61bde14b0f9c7b0d9c6c57d30d08f19145cd34334f70db19610832b2701b4ac717c547c7286dac6
7
+ data.tar.gz: 3245311e591e91bde4efe5d507d24df2938377df86d42b7111d6a87da7488f6eda932b7fcb1b053e1e71c89934a4845542e531c5b291bfbda57bd036664017c0
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .byebug_history
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem "activesupport", '~> 5.0'
data/Gemfile.lock CHANGED
@@ -1,12 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yml_record (0.1.1)
4
+ yml_record (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activesupport (5.2.8)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 0.7, < 2)
12
+ minitest (~> 5.1)
13
+ tzinfo (~> 1.1)
14
+ concurrent-ruby (1.1.10)
9
15
  diff-lcs (1.4.4)
16
+ i18n (1.10.0)
17
+ concurrent-ruby (~> 1.0)
18
+ minitest (5.15.0)
10
19
  rake (12.3.3)
11
20
  rspec (3.10.0)
12
21
  rspec-core (~> 3.10.0)
@@ -21,14 +30,18 @@ GEM
21
30
  diff-lcs (>= 1.2.0, < 2.0)
22
31
  rspec-support (~> 3.10.0)
23
32
  rspec-support (3.10.2)
33
+ thread_safe (0.3.6)
34
+ tzinfo (1.2.9)
35
+ thread_safe (~> 0.1)
24
36
 
25
37
  PLATFORMS
26
38
  ruby
27
39
 
28
40
  DEPENDENCIES
41
+ activesupport (~> 5.0)
29
42
  rake (~> 12.0)
30
43
  rspec (~> 3.0)
31
44
  yml_record!
32
45
 
33
46
  BUNDLED WITH
34
- 2.1.2
47
+ 2.1.4
data/README.md CHANGED
@@ -29,7 +29,7 @@ Create an ApplicationYmlRecord model that inherits from YmlRecord::Base
29
29
  Create a model that will be backed by a yml data file and inherit from ApplicationYmlRecord.
30
30
  ```
31
31
  # app/models/example_model.rb
32
- class ExampleModel < YamlRecord::Base; end
32
+ class ExampleModel < ApplicationYmlRecord
33
33
  ```
34
34
 
35
35
  Add a yml file (named the same as your model) to the `config/data/` folder
@@ -51,8 +51,104 @@ ExampleModel.find(1) #=> first instance of ExampleModel
51
51
  etc
52
52
  ```
53
53
 
54
+ The automatic folder location for the yml files is `config/data/` but this can be manually overwritten
55
+ The automatic file name for each model is the demodulized snakecase class name (e.g `App::ExampleClass` => `example_class.yml`)
56
+
57
+ This automatic functionality can be overwritten when needed
58
+ ```
59
+ # to overwrite individual class's data filename to `bar.yml`
60
+ class Foo < ApplicationYmlRecord
61
+ self.filename = 'bar'
62
+ end
63
+
64
+ # to overwrite data folder location
65
+ class ApplicationYmlRecord < YamlRecord::Base
66
+ self.filepath = 'another/folder'
67
+ end
68
+ ```
69
+ will look for data in `another/folder/bar/yml`
70
+
54
71
  See below for specific functionality implementations.
72
+ The implementation examples assume the following setup
73
+ ```
74
+ # example.yaml
75
+ - id: 1
76
+ old: true
77
+ colour: :green
78
+ - id: 2
79
+ colour: :red
80
+ old: true
81
+ - id: 3
82
+ colour: :red
83
+ old: false
84
+
85
+ class Example < YamlRecord::Base
86
+ end
87
+ ```
55
88
 
89
+ ### Class methods
90
+ #### Scopes
91
+ Scopes will return a chainable relation with instances that match the attributes similar to active record relations
92
+ ```
93
+ Example.where(old: true).where(colour: :red) #=> [<Example id: 1 />]
94
+ is the same as
95
+ Example.where(old: true, colour: :red)
96
+ ```
97
+
98
+ ### Relating to YamlRecord classes
99
+ Other classes can relate to yaml record classes using an active record style integration
100
+ #### Has Many
101
+ When storing primary keys of yaml records on another class, the belongs_to method can be used to create a parent like relationship.
102
+ If the other class is dynamic (e.g: backed by a database) then the relationship can be set to dynamic (default).
103
+ Otherwise (e.g: that class is also a yaml record) the relationship can be set to being not dynamic.
104
+ ```
105
+ class Child
106
+ attr_accessor :example_id
107
+
108
+ YmlRecord.relationships.belongs_to self, :example
109
+ end
110
+ ```
111
+ This will add `Child#example` and `Child.example=(other_example)` instance methods.
112
+
113
+ The following will mark this relationship as static (not dynamic), which will not create the setter method (`Child.example=(other_example)`)
114
+ ```
115
+ YmlRecord.relationships.belongs_to self, :example, dynamic: false
116
+ ```
117
+
118
+ The following keys can all be manually set in the same way as with active record belongs to:
119
+ - foreign_key
120
+ - primary_key
121
+ - class_name
122
+
123
+ If using active record to relate to yaml records, the following can be added to the application record to streamline implementation
124
+
125
+ ```
126
+ class Car < ApplicationYmlRecord; end
127
+
128
+ class ApplicationRecord < ActiveRecord::Base
129
+ def self.belongs_to(name, scope = nil, yml_relationship: false, **opts, &block)
130
+ return super(name, scope, **opts, &block)
131
+
132
+ YmlRecord.relationships.belongs_to self, name, scope, **opts, &block
133
+ end
134
+ end
135
+
136
+ # has db column of car_id (of type corresponding to car primary key)
137
+ class Driver < ApplicationRecord
138
+ belongs_to :car, yml_relationship: true
139
+ end
140
+ ```
141
+
142
+ ### Instance methods
143
+ #### Boolean methods
144
+
145
+ When an attribute is a boolean a boolean instance method is automatically created.
146
+ ```
147
+ Example.find(1).old? #=> true
148
+ Example.find(2).old? #=> false
149
+ ```
150
+
151
+ ### TODO documentation
56
152
  TODO: document implementation of custom filename
57
153
  TODO: document implementation of custom identifier
58
154
  TODO: document implementation of scope
@@ -61,12 +157,10 @@ TODO: document implementation of enum
61
157
  ## Future implementations
62
158
  TODO: document
63
159
 
64
- - [ ] default boolean methods. Currently need to specifically set up boolean methods.
65
160
  - [ ] setting data folder in initializer for gem
66
161
  - [ ] allow setting of specific data for specific deployments
67
162
 
68
163
 
69
-
70
164
  ## Development
71
165
 
72
166
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,6 +1,24 @@
1
+ require 'yml_record/helpers/delegate_missing_to.rb'
1
2
  require 'ostruct'
2
3
 
3
4
  module YmlRecord
4
5
  # class to hold attributes, just hold and return for now
5
- class Attributes < OpenStruct; end
6
+ class Attributes
7
+ extend DelegateMissingTo
8
+ delegate_missing_to :store
9
+
10
+ def initialize(**opts)
11
+ new_opts = opts.each_with_object({}) do |(key, value), acc|
12
+ if [true, false].include?(value) && !key.to_s.end_with?('?')
13
+ acc["#{key}?"] = value
14
+ end
15
+ acc[key] = value
16
+ end
17
+ @store = OpenStruct.new(**new_opts)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :store
23
+ end
6
24
  end
@@ -29,9 +29,7 @@ module YmlRecord
29
29
  protected
30
30
 
31
31
  def boolean_columns(*keys)
32
- keys.each do |key|
33
- define_method("#{key}?") { send(key) }
34
- end
32
+ raise NotImplementedError, 'this method is no longer necessary, data with a boolean value automatically generates a `?` getter'
35
33
  end
36
34
 
37
35
  private
@@ -4,7 +4,7 @@ module YmlRecord
4
4
  protected
5
5
 
6
6
  def data
7
- @data ||= YAML.load_file(filepath)
7
+ @data ||= YAML.load_file(filelocation)
8
8
  end
9
9
 
10
10
  private
@@ -16,7 +16,11 @@ module YmlRecord
16
16
  end
17
17
 
18
18
  def filepath
19
- @filepath ||= "config/data/#{filename}.yml"
19
+ @filepath ||= 'config/data'
20
+ end
21
+
22
+ def filelocation
23
+ @filelocation ||= "#{filepath}/#{filename}.yml"
20
24
  end
21
25
  end
22
26
  end
@@ -0,0 +1,39 @@
1
+ require 'active_support/core_ext/string'
2
+
3
+ module YmlRecord
4
+ module RelationshipBuilders
5
+ class BelongsTo
6
+ def self.build(model, name, scope = nil, **options, &_block)
7
+ new(model, name, scope, **options).build
8
+ end
9
+
10
+ def initialize(model, name, scope, dynamic: true, **options)
11
+ @model = model
12
+ @name = name
13
+ raise(NotImplementedError, 'yml record belongs to with scope is not yet implemented') if !!scope
14
+ @dynamic = dynamic
15
+ @options = options
16
+ end
17
+
18
+ def build
19
+ klass = (options.fetch(:class_name, nil) || name.to_s.camelize).constantize
20
+ klass_primary_key = options.fetch(:primay_key, klass.primary_key)
21
+ foreign_key = options.fetch(:foreign_key, "#{name}_#{klass_primary_key}")
22
+
23
+ model.define_method name do
24
+ klass.find_by(klass_primary_key => send(foreign_key))
25
+ end
26
+
27
+ if dynamic
28
+ model.define_method "#{name}=" do |instance|
29
+ self.send("#{foreign_key}=", instance.send(klass_primary_key))
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :model, :name, :dynamic, :options
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ require 'yml_record/relationship_builders/belongs_to.rb'
2
+
3
+ module YmlRecord
4
+ module RelationshipBuilders
5
+ def self.belongs_to(*args, **opts, &block)
6
+ BelongsTo.build(*args, **opts, &block)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module YmlRecord
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/yml_record.rb CHANGED
@@ -1,6 +1,11 @@
1
1
  require 'yml_record/base'
2
2
  require "yml_record/version"
3
+ require 'yml_record/relationship_builders'
3
4
 
4
5
  module YmlRecord
5
6
  class Error < StandardError; end
7
+
8
+ def self.relationships
9
+ YmlRecord::RelationshipBuilders
10
+ end
6
11
  end
data/yml_record.gemspec CHANGED
@@ -11,12 +11,11 @@ Gem::Specification.new do |spec|
11
11
  spec.homepage = "https://rubygems.org/gems/yml_record"
12
12
  spec.license = "MIT"
13
13
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+ spec.metadata["source_code_uri"] = "https://github.com/tjbarker/yml_record#readme"
14
15
 
15
- # TODO: do later cause I CBF now
16
16
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
17
17
 
18
18
  # spec.metadata["homepage_uri"] = spec.homepage
19
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
20
19
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21
20
 
22
21
  # Specify which files should be added to the gem when it is released.
@@ -24,6 +23,7 @@ Gem::Specification.new do |spec|
24
23
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
25
24
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
25
  end
26
+
27
27
  spec.bindir = "exe"
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yml_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Barker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-19 00:00:00.000000000 Z
11
+ date: 2022-07-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A gem for presenting ActiveRecord like interface for yml backed models
14
14
  email:
@@ -38,12 +38,15 @@ files:
38
38
  - lib/yml_record/builders/scope.rb
39
39
  - lib/yml_record/helpers/delegate_missing_to.rb
40
40
  - lib/yml_record/relation.rb
41
+ - lib/yml_record/relationship_builders.rb
42
+ - lib/yml_record/relationship_builders/belongs_to.rb
41
43
  - lib/yml_record/version.rb
42
44
  - yml_record.gemspec
43
45
  homepage: https://rubygems.org/gems/yml_record
44
46
  licenses:
45
47
  - MIT
46
- metadata: {}
48
+ metadata:
49
+ source_code_uri: https://github.com/tjbarker/yml_record#readme
47
50
  post_install_message:
48
51
  rdoc_options: []
49
52
  require_paths:
@@ -59,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
62
  - !ruby/object:Gem::Version
60
63
  version: '0'
61
64
  requirements: []
62
- rubygems_version: 3.1.6
65
+ rubygems_version: 3.1.2
63
66
  signing_key:
64
67
  specification_version: 4
65
68
  summary: A gem for presenting ActiveRecord like interface for yml backed models