local_model 0.1.12 → 0.1.14
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 +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -2
- data/README.md +30 -4
- data/Rakefile +7 -4
- data/bin/local_model +5 -0
- data/lib/local_model/adapters/float_adapter.rb +2 -1
- data/lib/local_model/collection.rb +19 -1
- data/lib/local_model/csv.rb +24 -7
- data/lib/local_model/generators/initialize.rb +32 -0
- data/lib/local_model/helpers/pluralized_words.rb +0 -1
- data/lib/local_model/model.rb +19 -9
- data/lib/local_model/templates/data_accessor.erb +61 -0
- data/lib/local_model/templates/generate_model.erb +20 -0
- data/lib/local_model/templates/initializer.erb +7 -0
- data/lib/local_model/version.rb +1 -1
- data/lib/local_model.rb +1 -0
- data/local_model.gemspec +5 -2
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52fd36165c3ec49f275a899b9c687e99e91942c64d603542f5295dfbd6b4070a
|
4
|
+
data.tar.gz: 26992202b57f21466187744566b20f1be8a2701d15a3cb6975dcd4f5f389d902
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34dfb6506d823c13ecbe82869a7a60d3047e3842df78af576e7cf8b463422736bd95e103ef38b5ce57373e03f3a9d957ba83235984caec258aa593b348206d39
|
7
|
+
data.tar.gz: 989578a3bab8d8bb7d60fc1556b2f28c0c0e718f9c2d0054b178c1e2a460857fba0108198ce9ed13c5c0b7adec08a9f3ce21eaf8e3cb46bca9d0f871f754a83f
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
local_model (0.1.
|
4
|
+
local_model (0.1.13)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -31,6 +31,7 @@ GEM
|
|
31
31
|
diff-lcs (>= 1.2.0, < 2.0)
|
32
32
|
rspec-support (~> 3.10.0)
|
33
33
|
rspec-support (3.10.2)
|
34
|
+
thor (1.2.1)
|
34
35
|
|
35
36
|
PLATFORMS
|
36
37
|
x86_64-linux
|
@@ -42,6 +43,7 @@ DEPENDENCIES
|
|
42
43
|
pry (~> 0.14.1)
|
43
44
|
rake (~> 13.0)
|
44
45
|
rspec (~> 3.10)
|
46
|
+
thor (~> 1.2)
|
45
47
|
|
46
48
|
BUNDLED WITH
|
47
|
-
2.
|
49
|
+
2.3.14
|
data/README.md
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# LocalModel
|
2
2
|
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/local_model`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
|
-
|
7
3
|
## Installation
|
8
4
|
|
9
5
|
Add this line to your application's Gemfile:
|
@@ -22,6 +18,36 @@ Or install it yourself as:
|
|
22
18
|
|
23
19
|
## Usage
|
24
20
|
|
21
|
+
Use the generator:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
bundle add local_model
|
25
|
+
```
|
26
|
+
```
|
27
|
+
bundle exec local_model --namespace DesiredNamespace
|
28
|
+
```
|
29
|
+
Note: `--namespace` is optional and will default to `InMemory`
|
30
|
+
This creates a rails initializer which sets some config options,
|
31
|
+
and a `DataAccessor` class which you can use to switch between your `LocalModel` objects and your `ActiveRecord` objects.
|
32
|
+
|
33
|
+
Recommend adding:
|
34
|
+
|
35
|
+
`config/application.rb`
|
36
|
+
```ruby
|
37
|
+
config.autoload_paths << config.root.join('lib')
|
38
|
+
```
|
39
|
+
|
40
|
+
so you get all of these files.
|
41
|
+
|
42
|
+
You can set an environment variable `USE_LOCAL_MODELS` to `true` or `false` to globally decide what to use.
|
43
|
+
|
44
|
+
|
45
|
+
You also now can use a rake task to generate your `LocalModel` models:
|
46
|
+
`rake local_model:create_model\[User\]`
|
47
|
+
(The `\`s should only be necessary in zsh, not bash)
|
48
|
+
|
49
|
+
OR, you can manually:
|
50
|
+
|
25
51
|
Create your schema:
|
26
52
|
|
27
53
|
```rb
|
data/Rakefile
CHANGED
@@ -5,9 +5,12 @@ RSpec::Core::RakeTask.new(:spec)
|
|
5
5
|
|
6
6
|
task :default => :spec
|
7
7
|
|
8
|
-
desc "
|
9
|
-
task :
|
10
|
-
require 'pry'
|
8
|
+
desc "environment"
|
9
|
+
task :environment do
|
11
10
|
require_relative './lib/local_model.rb'
|
12
|
-
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "run file generator"
|
14
|
+
task :generate => :environment do
|
15
|
+
LocalModel::Generator.new.invoke_all
|
13
16
|
end
|
data/bin/local_model
ADDED
@@ -26,7 +26,7 @@ class LocalModel::Collection < Array
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def where(**args)
|
29
|
-
self.filter do |el|
|
29
|
+
arr = self.filter do |el|
|
30
30
|
found = true
|
31
31
|
args.each do |k,v|
|
32
32
|
if el.send(k.to_s) != v
|
@@ -36,6 +36,24 @@ class LocalModel::Collection < Array
|
|
36
36
|
end
|
37
37
|
found
|
38
38
|
end
|
39
|
+
self.class.create_from(
|
40
|
+
array: arr,
|
41
|
+
for_model: model,
|
42
|
+
for_collection_class: nil,
|
43
|
+
add_to_collection_proc: ->(a,b) { raise NoMethodError.new("Cannot add to this collection") }
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_by(**args)
|
48
|
+
where(**args).first
|
49
|
+
end
|
50
|
+
|
51
|
+
def first
|
52
|
+
self[0]
|
53
|
+
end
|
54
|
+
|
55
|
+
def last
|
56
|
+
self[-1]
|
39
57
|
end
|
40
58
|
|
41
59
|
end
|
data/lib/local_model/csv.rb
CHANGED
@@ -37,6 +37,10 @@ class LocalModel::CSV < LocalModel::Model
|
|
37
37
|
schema_data
|
38
38
|
end
|
39
39
|
|
40
|
+
self.define_method :schema_defaults do
|
41
|
+
builder.defaults
|
42
|
+
end
|
43
|
+
|
40
44
|
if !File.file?(self.storage_path)
|
41
45
|
CSV.open(self.storage_path, 'wb') do |csv|
|
42
46
|
csv << cols.map(&:to_s)
|
@@ -63,7 +67,7 @@ class LocalModel::CSV < LocalModel::Model
|
|
63
67
|
end
|
64
68
|
|
65
69
|
def self.where(**args)
|
66
|
-
all_records do |row|
|
70
|
+
arr = all_records do |row|
|
67
71
|
found = true
|
68
72
|
args.each do |k,v|
|
69
73
|
if row[k] != v
|
@@ -73,6 +77,12 @@ class LocalModel::CSV < LocalModel::Model
|
|
73
77
|
end
|
74
78
|
found
|
75
79
|
end.map{|r| new_from_record(r) }
|
80
|
+
LocalModel::Collection.create_from(
|
81
|
+
array: arr,
|
82
|
+
for_model: self,
|
83
|
+
for_collection_class: nil,
|
84
|
+
add_to_collection_proc: ->(a,b) { raise NoMethodError.new("Cannot add to this collection") }
|
85
|
+
)
|
76
86
|
end
|
77
87
|
|
78
88
|
def self.find_by(**args)
|
@@ -108,11 +118,7 @@ class LocalModel::CSV < LocalModel::Model
|
|
108
118
|
end
|
109
119
|
|
110
120
|
def self.find(id)
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.find!(id)
|
115
|
-
found_record = find(id)
|
121
|
+
found_record = self.find_by(id: id)
|
116
122
|
if !found_record
|
117
123
|
raise LocalModel::RecordNotFound.new
|
118
124
|
else
|
@@ -120,6 +126,14 @@ class LocalModel::CSV < LocalModel::Model
|
|
120
126
|
end
|
121
127
|
end
|
122
128
|
|
129
|
+
def self.find_or_create_by(**args)
|
130
|
+
found_obj = find_by(**args)
|
131
|
+
return found_obj if found_obj
|
132
|
+
create(**args)
|
133
|
+
end
|
134
|
+
|
135
|
+
# TODO: Move necessary methods to model.rb
|
136
|
+
|
123
137
|
def self.create(**args)
|
124
138
|
inst = new(**args)
|
125
139
|
inst.save
|
@@ -133,6 +147,9 @@ class LocalModel::CSV < LocalModel::Model
|
|
133
147
|
end
|
134
148
|
|
135
149
|
def initialize(**args)
|
150
|
+
self.schema_defaults.each do |property, value|
|
151
|
+
self.send("#{property}=", value)
|
152
|
+
end
|
136
153
|
args.each do |k,v|
|
137
154
|
self.send("#{k}=", v)
|
138
155
|
end
|
@@ -145,7 +162,7 @@ class LocalModel::CSV < LocalModel::Model
|
|
145
162
|
|
146
163
|
def reload
|
147
164
|
raise LocalModel::RecordNotFound if !self.id
|
148
|
-
self.class.find
|
165
|
+
self.class.find(self.id)
|
149
166
|
end
|
150
167
|
|
151
168
|
def destroy
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thor/group'
|
3
|
+
|
4
|
+
module LocalModel
|
5
|
+
module Generators
|
6
|
+
class Initialize < Thor::Group
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
class_option :namespace, default: "InMemory"
|
10
|
+
|
11
|
+
desc 'Create required files'
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
File.dirname(__FILE__) + '/../'
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_initializer
|
18
|
+
@namespace_classname = options[:namespace]
|
19
|
+
template('templates/initializer.erb', 'config/initializers/local_model.rb')
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_data_accessor
|
23
|
+
template('templates/data_accessor.erb', 'lib/data_accessor.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_model_generator
|
27
|
+
@class_namespace_snake = LocalModel::Functions.camel_to_snake(@namespace_classname)
|
28
|
+
template('templates/generate_model.erb', 'lib/tasks/local_model.rake')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/local_model/model.rb
CHANGED
@@ -33,7 +33,7 @@ class LocalModel::Model
|
|
33
33
|
association_class = Object.const_get(association_class_name)
|
34
34
|
end
|
35
35
|
id = self.send(keyname)
|
36
|
-
association_class.
|
36
|
+
association_class.find_by(id: id)
|
37
37
|
end
|
38
38
|
|
39
39
|
define_method "#{association}=" do |association_obj|
|
@@ -91,7 +91,7 @@ class LocalModel::Model
|
|
91
91
|
define_method association do
|
92
92
|
association_class = Object.const_get(association_classname)
|
93
93
|
LocalModel::Collection.create_from(
|
94
|
-
array: self.send(through).map{|through_obj| association_class.
|
94
|
+
array: self.send(through).map{|through_obj| association_class.find_by(id: through_obj.send(belongs_to_id_sym))},
|
95
95
|
for_model: self,
|
96
96
|
for_collection_class: association_class,
|
97
97
|
add_to_collection_proc: add_to_collection
|
@@ -192,37 +192,47 @@ class LocalModel::Model
|
|
192
192
|
class SchemaBuilder
|
193
193
|
|
194
194
|
attr_reader :schema
|
195
|
+
attr_reader :defaults
|
195
196
|
|
196
197
|
def initialize(model)
|
197
198
|
@model = model
|
198
199
|
@schema = { id: :integer }
|
199
200
|
@model.attr_accessor :id
|
201
|
+
@defaults = {}
|
200
202
|
end
|
201
203
|
|
202
|
-
def
|
204
|
+
def set_default(name, default)
|
205
|
+
@defaults[name] = default if !default.nil?
|
206
|
+
end
|
207
|
+
|
208
|
+
def string(name, default: nil)
|
203
209
|
@model.attr_accessor name
|
204
210
|
@schema[name] = :string
|
211
|
+
set_default(name, default)
|
205
212
|
end
|
206
213
|
|
207
|
-
def integer(name)
|
214
|
+
def integer(name, default: nil)
|
208
215
|
@model.attr_accessor name
|
209
216
|
@schema[name] = :integer
|
217
|
+
set_default(name, default)
|
210
218
|
end
|
211
219
|
|
212
|
-
def boolean(name)
|
220
|
+
def boolean(name, default: nil)
|
213
221
|
@model.attr_accessor name
|
214
222
|
@schema[name] = :boolean
|
223
|
+
set_default(name, default)
|
215
224
|
end
|
216
225
|
|
217
|
-
def float(name)
|
226
|
+
def float(name, default: nil)
|
218
227
|
@model.attr_accessor name
|
219
228
|
@schema[name] = :float
|
229
|
+
set_default(name, default)
|
220
230
|
end
|
221
231
|
|
222
|
-
def datetime(name)
|
232
|
+
def datetime(name, default: nil)
|
223
233
|
@model.attr_accessor name
|
224
234
|
@schema[name] = :datetime
|
235
|
+
set_default(name, default)
|
225
236
|
end
|
226
|
-
|
227
237
|
end
|
228
|
-
end
|
238
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module DataAccessor
|
2
|
+
class Base
|
3
|
+
class Accessors
|
4
|
+
LOCAL = :local
|
5
|
+
ACTIVE_RECORD = :active_record
|
6
|
+
|
7
|
+
NAMESPACES = {
|
8
|
+
LOCAL => <%= @namespace_classname %>,
|
9
|
+
ACTIVE_RECORD => Object
|
10
|
+
}
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
@@strategy = ENV["USE_LOCAL_MODELS"] ? Accessors::LOCAL : Accessors::ACTIVE_RECORD
|
15
|
+
@@exceptions = Set.new([])
|
16
|
+
|
17
|
+
def self.set_strategy(strat)
|
18
|
+
if strat.to_sym == :local
|
19
|
+
@@strategy = Accessors::LOCAL
|
20
|
+
else
|
21
|
+
@@strategy = Accessors::ACTIVE_RECORD
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.klass(klass_name)
|
26
|
+
namespace = get_namespace_for(klass_name)
|
27
|
+
namespaced_klass_name = "#{namespace}::#{klass_name.to_s}"
|
28
|
+
namespaced_klass = Object.const_get(namespaced_klass_name)
|
29
|
+
end
|
30
|
+
private_class_method :klass
|
31
|
+
|
32
|
+
def self.get_namespace
|
33
|
+
Accessors::NAMESPACES[@@strategy]
|
34
|
+
end
|
35
|
+
private_class_method :get_namespace
|
36
|
+
|
37
|
+
def self.get_namespace_for(klass)
|
38
|
+
exception_strategy = @@strategy == Accessors::ACTIVE_RECORD ? Accessors::LOCAL : Accessors::ACTIVE_RECORD
|
39
|
+
exception_namespace = Accessors::NAMESPACES[exception_strategy]
|
40
|
+
if @@exceptions.include?(klass.to_s.to_sym)
|
41
|
+
exception_namespace
|
42
|
+
else
|
43
|
+
get_namespace
|
44
|
+
end
|
45
|
+
end
|
46
|
+
private_class_method :get_namespace_for
|
47
|
+
|
48
|
+
def self.set_exceptions(exceptions)
|
49
|
+
@@exceptions = Set.new(exceptions.map(&:to_sym))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Example - find user
|
53
|
+
# def self.find_user(id)
|
54
|
+
# ref = klass(:User)
|
55
|
+
# ref.find(id)
|
56
|
+
# end
|
57
|
+
# private_class_method :find_user
|
58
|
+
|
59
|
+
# MARK: PUBLIC GETTERS
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
namespace :local_model do
|
3
|
+
|
4
|
+
desc "Generate LocalModel model"
|
5
|
+
task :create_model, [:klass_name] => :environment do |_t, args|
|
6
|
+
klass_name = args[:klass_name]
|
7
|
+
model_code = <<~RUBY
|
8
|
+
class <%= @namespace_classname %>::#{klass_name} < LocalModel::CSV
|
9
|
+
schema do |t|
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
RUBY
|
14
|
+
|
15
|
+
dir = Rails.root.join('lib', '<%= @class_namespace_snake%>')
|
16
|
+
Dir.mkdir(dir) unless File.exists?(dir)
|
17
|
+
filename = "#{dir}/#{klass_name.underscore}.rb"
|
18
|
+
File.open(filename, 'w') { |f| f.write(model_code) }
|
19
|
+
end
|
20
|
+
end
|
data/lib/local_model/version.rb
CHANGED
data/lib/local_model.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative './local_model/helpers/functions'
|
|
14
14
|
require_relative './local_model/helpers/pluralized_words'
|
15
15
|
require_relative './local_model/model'
|
16
16
|
require_relative './local_model/csv'
|
17
|
+
require_relative './local_model/generators/initialize'
|
17
18
|
|
18
19
|
module LocalModel
|
19
20
|
class Error < StandardError; end
|
data/local_model.gemspec
CHANGED
@@ -30,8 +30,11 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
31
31
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
32
32
|
end
|
33
|
-
spec.bindir = "exe"
|
34
|
-
spec.
|
33
|
+
# spec.bindir = "exe"
|
34
|
+
spec.bindir = "bin"
|
35
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
36
|
+
spec.executables << 'local_model'
|
37
|
+
# spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
38
|
spec.require_paths = ["lib"]
|
36
39
|
|
37
40
|
spec.add_development_dependency "bundler", "~> 2.2"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: local_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Shute
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,7 +56,10 @@ description: This is meant to help facilitate an API-first strategy when creatin
|
|
56
56
|
web apps with RoR
|
57
57
|
email:
|
58
58
|
- micah.shute@gmail.com
|
59
|
-
executables:
|
59
|
+
executables:
|
60
|
+
- console
|
61
|
+
- local_model
|
62
|
+
- setup
|
60
63
|
extensions: []
|
61
64
|
extra_rdoc_files: []
|
62
65
|
files:
|
@@ -70,6 +73,7 @@ files:
|
|
70
73
|
- README.md
|
71
74
|
- Rakefile
|
72
75
|
- bin/console
|
76
|
+
- bin/local_model
|
73
77
|
- bin/setup
|
74
78
|
- lib/local_model.rb
|
75
79
|
- lib/local_model/adapters/boolean_adapter.rb
|
@@ -82,10 +86,14 @@ files:
|
|
82
86
|
- lib/local_model/csv.rb
|
83
87
|
- lib/local_model/errors/record_invalid.rb
|
84
88
|
- lib/local_model/errors/record_not_found.rb
|
89
|
+
- lib/local_model/generators/initialize.rb
|
85
90
|
- lib/local_model/helpers/functions.rb
|
86
91
|
- lib/local_model/helpers/pluralized_words.rb
|
87
92
|
- lib/local_model/model.rb
|
88
93
|
- lib/local_model/sandbox.rb
|
94
|
+
- lib/local_model/templates/data_accessor.erb
|
95
|
+
- lib/local_model/templates/generate_model.erb
|
96
|
+
- lib/local_model/templates/initializer.erb
|
89
97
|
- lib/local_model/version.rb
|
90
98
|
- local_model.gemspec
|
91
99
|
homepage: https://github.com/micahshute/local_model
|