ez 1.5.0.5 → 1.9.2
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/README.md +36 -85
- data/bin/console +14 -0
- data/ez.gemspec +1 -0
- data/lib/ez.rb +31 -38
- data/lib/ez/config.rb +59 -0
- data/lib/ez/domain_modeler.rb +75 -23
- data/lib/ez/model.rb +2 -20
- data/lib/ez/rails_updater.rb +60 -0
- data/lib/ez/schema_modifier.rb +1 -0
- data/lib/ez/version.rb +1 -1
- data/lib/tasks/ez_tasks.rake +7 -53
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb03b6da20e1afb0c548a1d8be3ba5efaaea9922
|
4
|
+
data.tar.gz: 50f53f9864921ec57b2f7d3f70dfc75ec01ba486
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 284b6ce37d4950607c14298fbd63609fdcad4f6ea6db23f15f844a2765d1c288168aad84c92e59a9bed72ae6d500f660c1cf2aac324a8e91439d14f977e648dd
|
7
|
+
data.tar.gz: fcb66139091f785ab8c0fd4567fc50b3216f97e4c82df61f325088ae1bc21afe37cef1ac824f491aa234f65af72b407f4e237c1b88fecdafee6c5e915cb93c70
|
data/README.md
CHANGED
@@ -11,10 +11,11 @@ _NOTE: For Rails < 5.0, use version 1.3_.
|
|
11
11
|
Easy domain modeling in Rails without migrations.
|
12
12
|
|
13
13
|
* Applies instant schema changes based on a file named `db/models.yml`.
|
14
|
+
* Schema changes applied automatically when code is reloaded.
|
14
15
|
* Diffs are determined automatically and applied to the database.
|
15
16
|
* Embraces Rails' column naming conventions by inferring columns types based on the name.
|
16
|
-
* Enhances the
|
17
|
-
*
|
17
|
+
* Enhances the Rails Console with customized AwesomePrint and Hirb integration
|
18
|
+
* Adds two new ActiveRecord methods: `.sample(n = 1)` and `.none?`
|
18
19
|
|
19
20
|
|
20
21
|
## Usage
|
@@ -23,80 +24,66 @@ Easy domain modeling in Rails without migrations.
|
|
23
24
|
gem 'ez'
|
24
25
|
```
|
25
26
|
|
26
|
-
Then
|
27
|
-
|
28
|
-
```
|
29
|
-
rails db:migrate
|
30
|
-
```
|
31
|
-
|
32
|
-
or (Rails 4.x)
|
33
|
-
```
|
34
|
-
rake db:migrate
|
35
|
-
```
|
36
|
-
|
37
|
-
to generate a skeleton `db/models.yml` that you should edit.
|
27
|
+
Then start your server or console to force the initial generation of
|
28
|
+
`db/models.yml` and a configuation file named `.ez`.
|
38
29
|
|
30
|
+
Alternatively, you can run `rails db:migrate` to generate these files without running your app.
|
39
31
|
|
40
32
|
## Get Started
|
41
33
|
|
42
|
-
1.
|
43
|
-
|
44
|
-
2. Use `db/models.yml` to define your schema. Database schema changes are applied directly and triggered automatically in development mode. (`rake db:migrate` will also trigger the changes). Foreign-key indexes will be generated automatically.
|
34
|
+
1. Use `db/models.yml` to define your schema. Database schema changes are applied directly and triggered automatically in development mode. (`rails db:migrate` will also trigger the changes). Foreign-key indexes will be generated automatically.
|
45
35
|
|
46
|
-
|
36
|
+
2. Run `rails db:migrate:preview` to do a "dry run" and see what would change based your `db/models.yml` file.
|
47
37
|
|
48
|
-
4. Run `rake db:migrate:preview` to do a "dry run" and see what would change based your `db/models.yml` file.
|
49
38
|
|
50
|
-
|
39
|
+
2. Use the `.ez` file to control functionality.
|
51
40
|
|
52
41
|
|
53
|
-
|
42
|
+
|Config setting|Default|Description|
|
43
|
+
|----|----|----|
|
44
|
+
|models|true|Watches `models.yml` for changes. Set to `false` to turn off all functionality|
|
45
|
+
|restful_routes|true|Adds `resources :<tablename>` to routes.rb for each model|
|
46
|
+
|controllers|true|Generates one controller per model with 7 empty methods.
|
47
|
+
|views|true|Generates the view folder for each model, with 7 empty views.
|
48
|
+
|timestamps|true|Generates `created_at` and `updated_at` columns on every model.
|
54
49
|
|
55
|
-
* This gem enhances `db:migrate` to incorporate the `db/models.yml` file automatically.
|
56
|
-
* Run `rails db:migrate` (Rails 5.x) or `rake db:migrate` (Rails 4.x) to initially generate a file named `db/models.yml`. It will have some self-documenting comments inside of it.
|
57
|
-
* Just run `rails db:migrate` (or `rake db:migrate`) whenever you modify `db/models.yml`.
|
58
|
-
* Using `reload!` inside the rails console is an alternative to the `db:migrate` task.
|
59
|
-
* Pending migrations will be run *after* running table updates based on the `db/models.yml` file.
|
60
50
|
|
51
|
+
## Syntax Guide for `db/models.yml`**
|
61
52
|
|
62
|
-
|
63
|
-
|
64
|
-
It's just YML and the syntax is very simple:
|
53
|
+
It's just YAML. We recommend `text` instead of `string` columns but both are supported.
|
65
54
|
|
66
55
|
```
|
67
56
|
Book:
|
68
|
-
title:
|
69
|
-
copies_on_hand: integer
|
57
|
+
title: text
|
70
58
|
author_id: integer
|
71
59
|
created_at: datetime
|
72
60
|
updated_at: datetime
|
73
61
|
paperback: boolean
|
74
62
|
|
75
63
|
Author:
|
76
|
-
last_name:
|
77
|
-
first_name:
|
64
|
+
last_name: text
|
65
|
+
first_name: text
|
78
66
|
book_count: integer
|
79
67
|
```
|
80
68
|
|
81
69
|
**(Optional) Variations**
|
82
70
|
|
83
|
-
The colon after the model name is optional.
|
71
|
+
1. The colon after the model name is optional.
|
84
72
|
|
85
|
-
|
73
|
+
2. Rails conventions are embraced in `db/models.yml` resulting in these sensible defaults:
|
86
74
|
|
87
|
-
* If a column type isn't specified, it's assumed to be a `
|
88
|
-
* Column names ending in `_id` and `_count` are assumed to be of type `integer`.
|
89
|
-
* Column names ending in `_at` are assumed to be of type `datetime`.
|
90
|
-
* Column names ending in `_on` are assumed to be of type `date`.
|
75
|
+
* If a column type isn't specified, it's assumed to be a `text` column.
|
76
|
+
* Column names ending in `_id` and `_count` are assumed to be of type `integer`.
|
77
|
+
* Column names ending in `_at` are assumed to be of type `datetime`.
|
78
|
+
* Column names ending in `_on` are assumed to be of type `date`.
|
91
79
|
|
92
|
-
Also, note that `_id` columns are
|
80
|
+
Also, note that `_id` columns are assumed to be foreign keys and will **automatically generate a database index for that column**.
|
93
81
|
|
94
82
|
So the above models could be written as:
|
95
83
|
|
96
84
|
```
|
97
85
|
Book
|
98
86
|
title
|
99
|
-
copies_on_hand: integer
|
100
87
|
author_id
|
101
88
|
created_at
|
102
89
|
updated_at
|
@@ -109,72 +96,36 @@ Author
|
|
109
96
|
```
|
110
97
|
|
111
98
|
**Default Values**
|
112
|
-
You can specify default values for columns
|
99
|
+
You can specify default values for columns right after the column type:
|
113
100
|
|
114
101
|
```
|
115
102
|
Book
|
116
103
|
title
|
117
|
-
copies_on_hand: integer, default: 0
|
118
104
|
author_id
|
119
105
|
created_at
|
120
106
|
updated_at
|
121
|
-
paperback: boolean
|
107
|
+
paperback: boolean(false)
|
122
108
|
|
123
109
|
Author
|
124
110
|
last_name
|
125
111
|
first_name
|
126
|
-
book_count: integer
|
127
|
-
```
|
128
|
-
|
129
|
-
The syntax is forgiving, so the comma and colon are just for readability; this would work too:
|
130
|
-
|
131
|
-
```
|
132
|
-
Book
|
133
|
-
title
|
134
|
-
copies_on_hand: integer default 0
|
135
|
-
author_id
|
136
|
-
created_at
|
137
|
-
updated_at
|
138
|
-
paperback: boolean
|
139
|
-
|
140
|
-
Author
|
141
|
-
last_name
|
142
|
-
first_name
|
143
|
-
book_count: integer default 0
|
144
|
-
```
|
145
|
-
|
146
|
-
And for the extra lazy, like me, you can just use parentheses:
|
147
|
-
|
148
|
-
```
|
149
|
-
Book
|
150
|
-
title
|
151
|
-
copies_on_hand: integer(0)
|
152
|
-
author_id
|
153
|
-
created_at
|
154
|
-
updated_at
|
155
|
-
paperback: boolean
|
156
|
-
|
157
|
-
Author
|
158
|
-
last_name
|
159
|
-
first_name
|
160
|
-
book_count(0)
|
112
|
+
book_count: integer(0)
|
161
113
|
```
|
162
114
|
|
163
115
|
* Boolean columns are assumed to be given a default of `false` if not otherwise specified.
|
164
116
|
|
165
117
|
|
166
|
-
### 2.
|
118
|
+
### 2. ActiveRecord Enhancements
|
167
119
|
|
168
|
-
* Adds ActiveRecord::Base `.read` method so that models have complete *CRUD*: `.create`, `.read`, `.update`, and `.delete`. When given an integer, `.read` becomes a synonym for `.find`. When given a hash, it is a synonym for `.where`.
|
169
120
|
* Adds `.sample` method to choose a random row.
|
170
121
|
* Adds `.to_ez` to generate a snippet from legacy models that you can paste into models.yml.
|
171
122
|
|
172
123
|
|
173
|
-
|
174
124
|
### 3. Beginner-friendly "It Just Works" console
|
175
125
|
|
176
126
|
* Solves the "no connection" message in Rails >= 4.0.1 (if you try to inspect a model without making a query first) by establishing an initial connection to the development database.
|
177
127
|
* Shows helpful instructions when console starts, including the list of model classes found in the application.
|
178
|
-
*
|
179
|
-
*
|
180
|
-
*
|
128
|
+
* Activates AwesomePrint in the Rails consol.
|
129
|
+
* Uses Hirb for table-like display.
|
130
|
+
* Configures Hirb to allow nice table output for `ActiveRecord::Relation` collections
|
131
|
+
* Configures Hirb to produce hash-like output for single ActiveRecord objects
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ez"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/ez.gemspec
CHANGED
data/lib/ez.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
require "ez/version"
|
2
|
-
require 'ez/domain_modeler
|
3
|
-
require 'ez/model
|
2
|
+
require 'ez/domain_modeler'
|
3
|
+
require 'ez/model'
|
4
|
+
require 'ez/config'
|
5
|
+
require 'ez/rails_updater'
|
6
|
+
require 'awesome_print'
|
4
7
|
|
5
8
|
require 'hirb' if (Rails.env.development? || Rails.env.test?)
|
6
9
|
|
7
10
|
module EZ
|
8
11
|
module Console
|
9
|
-
def reload!
|
10
|
-
puts "Reloading code..."
|
12
|
+
def reload!
|
13
|
+
puts "Reloading code..."
|
11
14
|
if Rails::VERSION::MAJOR < 5
|
12
15
|
ActionDispatch::Reloader.cleanup!
|
13
16
|
ActionDispatch::Reloader.prepare!
|
@@ -15,19 +18,12 @@ module EZ
|
|
15
18
|
Rails.application.reloader.reload!
|
16
19
|
end
|
17
20
|
|
18
|
-
puts "Updating tables (if necessary) ..." if print
|
19
|
-
old_level = ActiveRecord::Base.logger.level
|
20
|
-
ActiveRecord::Base.logger.level = Logger::WARN
|
21
|
-
EZ::DomainModeler.generate_models_yml
|
22
|
-
EZ::DomainModeler.update_tables
|
23
|
-
EZ::DomainModeler.dump_schema
|
24
|
-
puts "Models: #{EZ::DomainModeler.models.to_sentence}"
|
25
|
-
ActiveRecord::Base.logger.level = old_level
|
26
21
|
true
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
30
25
|
|
26
|
+
|
31
27
|
module EZ
|
32
28
|
|
33
29
|
class Railtie < Rails::Railtie
|
@@ -37,46 +33,43 @@ module EZ
|
|
37
33
|
end
|
38
34
|
|
39
35
|
console do |app|
|
40
|
-
Rails::ConsoleMethods.send :prepend, EZ::Console
|
41
|
-
|
36
|
+
# Rails::ConsoleMethods.send :prepend, EZ::Console
|
37
|
+
AwesomePrint.irb!
|
42
38
|
|
43
|
-
|
44
|
-
ActiveRecord::Base.logger.level = Logger::WARN
|
45
|
-
EZ::DomainModeler.generate_models_yml
|
46
|
-
EZ::DomainModeler.update_tables(true)
|
47
|
-
ActiveRecord::Base.logger.level = old_level
|
39
|
+
Hirb.enable(pager: false) if (Rails.env.development? || Rails.env.test?) && defined?(Hirb)
|
48
40
|
|
49
41
|
I18n.enforce_available_locales = false
|
50
|
-
|
51
|
-
puts "-" * 60
|
52
|
-
puts
|
42
|
+
|
53
43
|
models = EZ::DomainModeler.models
|
44
|
+
puts
|
54
45
|
if models.any?
|
55
|
-
puts "Models: #{models.to_sentence}"
|
46
|
+
puts "Models: #{models.to_sentence}" if models.any?
|
56
47
|
puts
|
57
|
-
puts "Use this console to
|
58
|
-
puts
|
59
|
-
puts "HINTS:"
|
60
|
-
puts "* Type 'exit' (or press Ctrl-D) to when you're done."
|
61
|
-
puts "* Press Ctrl-C if things seem to get stuck."
|
62
|
-
puts "* Use the up/down arrows to repeat commands."
|
63
|
-
puts "* Type the name of a Model to see what columns it has." if models.any?
|
48
|
+
puts "Use this console to create, read, update, and delete rows from the database."
|
64
49
|
puts
|
65
50
|
end
|
66
|
-
|
51
|
+
puts "HINTS:"
|
52
|
+
puts "* Type 'exit' (or press CTRL-D) when you're done."
|
53
|
+
puts "* Press Ctrl-C if things seem to get stuck."
|
54
|
+
puts "* Use the up/down arrows to repeat commands."
|
55
|
+
puts "* Type the name of a Model to see what columns it has." if models.any?
|
56
|
+
puts
|
67
57
|
end
|
68
58
|
|
69
59
|
initializer "ez" do
|
70
60
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
61
|
+
if Rails::VERSION::MAJOR < 5
|
62
|
+
ActionDispatch::Reloader.to_prepare do
|
63
|
+
DomainModeler.automigrate
|
64
|
+
end
|
65
|
+
else
|
66
|
+
ActiveSupport::Reloader.to_prepare do
|
67
|
+
DomainModeler.automigrate
|
68
|
+
end
|
69
|
+
end
|
78
70
|
|
79
71
|
if (Rails.env.development? || Rails.env.test?)
|
72
|
+
|
80
73
|
module ::Hirb
|
81
74
|
# A Formatter object formats an output object (using Formatter.format_output) into a string based on the views defined
|
82
75
|
# for its class and/or ancestry.
|
data/lib/ez/config.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module EZ
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
DEFAULTS = { "models" => true,
|
6
|
+
"restful_routes" => true,
|
7
|
+
"controllers" => true,
|
8
|
+
"views" => true,
|
9
|
+
"timestamps" => true
|
10
|
+
}
|
11
|
+
|
12
|
+
def self.to_h
|
13
|
+
configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.save!
|
17
|
+
File.open(filename,"w") do |file|
|
18
|
+
file.write @config.to_yaml.sub(/^\-+$/,'')
|
19
|
+
end
|
20
|
+
@config
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.filename
|
24
|
+
File.join(Rails.root, '.ez')
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.configuration
|
28
|
+
@config ||= begin
|
29
|
+
if File.exist?(filename)
|
30
|
+
DEFAULTS.merge YAML.load_file(filename)
|
31
|
+
else
|
32
|
+
DEFAULTS
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.timestamps?
|
38
|
+
configuration["timestamps"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.routes?
|
42
|
+
configuration["restful_routes"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.models?
|
46
|
+
configuration["models"]
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.controllers?
|
50
|
+
configuration["controllers"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.views?
|
54
|
+
configuration["views"]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/ez/domain_modeler.rb
CHANGED
@@ -12,11 +12,37 @@ module EZ
|
|
12
12
|
# Valid formats for default values
|
13
13
|
DEFAULT_VALUE_REGEXES = [/\s*\((.+)?\)/, /\s+(.+)?\s*/, /,\s*default:\s*(.+)?\s*/]
|
14
14
|
|
15
|
-
def self.
|
15
|
+
def self.tables
|
16
16
|
tables = ActiveRecord::Base.connection.data_sources - ['schema_migrations', 'ar_internal_metadata']
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.models
|
17
20
|
tables.map { |t| t.classify }
|
18
21
|
end
|
19
22
|
|
23
|
+
def self.automigrate
|
24
|
+
if EZ::Config.models?
|
25
|
+
models_yml = File.join(Rails.root, 'db', 'models.yml')
|
26
|
+
schema_rb = File.join(Rails.root, 'db', 'schema.rb')
|
27
|
+
|
28
|
+
EZ::DomainModeler.generate_models_yml unless File.exist?(models_yml)
|
29
|
+
|
30
|
+
if !File.exist?(schema_rb) || (File.mtime(schema_rb) < File.mtime(models_yml))
|
31
|
+
puts "Updating your app based on models.yml..."
|
32
|
+
old_level = ActiveRecord::Base.logger.level
|
33
|
+
ActiveRecord::Base.logger.level = Logger::WARN
|
34
|
+
|
35
|
+
EZ::DomainModeler.update_tables
|
36
|
+
dump_schema if (Rails.env.development? || Rails.env.test?)
|
37
|
+
puts "Models: #{EZ::DomainModeler.models.to_sentence}"
|
38
|
+
ActiveRecord::Base.logger.level = old_level
|
39
|
+
end
|
40
|
+
|
41
|
+
EZ::RailsUpdater.update!
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
20
46
|
# Get the domain model as a hash
|
21
47
|
attr_reader :spec
|
22
48
|
|
@@ -31,7 +57,10 @@ module EZ
|
|
31
57
|
end
|
32
58
|
|
33
59
|
def self.dump_schema
|
34
|
-
|
60
|
+
require "active_record/schema_dumper"
|
61
|
+
File.open(File.join(Rails.root, 'db/schema.rb'), "w:utf-8") do |file|
|
62
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
63
|
+
end
|
35
64
|
end
|
36
65
|
|
37
66
|
def self.generate_models_yml
|
@@ -39,24 +68,42 @@ module EZ
|
|
39
68
|
unless File.exist?(filename)
|
40
69
|
File.open(filename, "w") do |f|
|
41
70
|
f.puts <<-EOS
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
71
|
+
# Example table for a typical Book model.
|
72
|
+
#
|
73
|
+
# Book
|
74
|
+
# title: text
|
75
|
+
# author_id: integer
|
76
|
+
# price: integer
|
77
|
+
# summary: text
|
78
|
+
# hardcover: boolean
|
79
|
+
#
|
80
|
+
# Indent consistently! Follow the above syntax exactly.
|
81
|
+
# Typical column choices are: string, text, integer, boolean, date, time, and datetime.
|
82
|
+
#
|
83
|
+
#
|
84
|
+
# About Default Values
|
85
|
+
# ----------------------------------------------------
|
86
|
+
# Default column values can be specified like this:
|
87
|
+
# price: integer(0)
|
88
|
+
#
|
89
|
+
# If not specified, Boolean columns always default to false.
|
90
|
+
#
|
91
|
+
#
|
92
|
+
# Convention-Based Defaults:
|
93
|
+
# ----------------------------------------------------
|
94
|
+
# You can omit the column type if it's a string, or if it's obviously an integer column:
|
95
|
+
#
|
96
|
+
#
|
97
|
+
# Book
|
98
|
+
# title
|
99
|
+
# author_id
|
100
|
+
# price: integer
|
101
|
+
# summary: text
|
102
|
+
# hardcover: boolean
|
103
|
+
#
|
104
|
+
# Complete details are in the README file online.
|
105
|
+
#
|
106
|
+
# Have fun!
|
60
107
|
EOS
|
61
108
|
end
|
62
109
|
end
|
@@ -96,9 +143,9 @@ module EZ
|
|
96
143
|
@spec = YAML.load(s)
|
97
144
|
parse_model_spec
|
98
145
|
|
99
|
-
|
100
|
-
|
101
|
-
|
146
|
+
puts "@spec:"
|
147
|
+
puts @spec.inspect
|
148
|
+
puts "-" * 10
|
102
149
|
end
|
103
150
|
|
104
151
|
def load_model_specs(filename = "db/models.yml")
|
@@ -122,6 +169,11 @@ module EZ
|
|
122
169
|
|
123
170
|
raise msg if msg
|
124
171
|
|
172
|
+
if EZ::Config.timestamps?
|
173
|
+
columns['created_at'] = 'datetime'
|
174
|
+
columns['updated_at'] = 'datetime'
|
175
|
+
end
|
176
|
+
|
125
177
|
columns.each do |column_name, column_type|
|
126
178
|
interpret_column_spec column_name, column_type, model
|
127
179
|
end
|
data/lib/ez/model.rb
CHANGED
@@ -1,25 +1,7 @@
|
|
1
1
|
class ActiveRecord::Base
|
2
2
|
|
3
|
-
def
|
4
|
-
"
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.read(args = nil)
|
8
|
-
if args.nil?
|
9
|
-
all
|
10
|
-
elsif args.is_a?(Integer)
|
11
|
-
find_by(id: args)
|
12
|
-
elsif args.is_a?(String) && args.to_i > 0 && !args.index(' ')
|
13
|
-
find_by(id: args)
|
14
|
-
elsif args.is_a?(Hash) && args.keys.count == 1 && args.keys[0].to_sym == :id
|
15
|
-
find_by(args)
|
16
|
-
else
|
17
|
-
where(args)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.sample
|
22
|
-
offset(rand(0...count)).first
|
3
|
+
def self.sample(n = 1)
|
4
|
+
n == 1 ? order("RANDOM()").first : order("RANDOM()").limit(n)
|
23
5
|
end
|
24
6
|
|
25
7
|
def self.none?
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module EZ
|
4
|
+
|
5
|
+
class RailsUpdater
|
6
|
+
|
7
|
+
METHODS = %w(index show destroy new create edit update)
|
8
|
+
VIEWS = %w(index show destroy new create edit update)
|
9
|
+
|
10
|
+
def self.update!
|
11
|
+
EZ::DomainModeler.tables.each do |table|
|
12
|
+
create_controller(table) if EZ::Config.controllers?
|
13
|
+
create_view_folder(table) if EZ::Config.views?
|
14
|
+
create_routes(table) if EZ::Config.routes?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_routes(table)
|
19
|
+
filename = File.join(Rails.root, 'config', 'routes.rb')
|
20
|
+
line = " resources :#{table}"
|
21
|
+
routes = File.read(filename)
|
22
|
+
if !routes.index(line)
|
23
|
+
line = "#{line}\n"
|
24
|
+
routes.sub!(/^\s*\# For details on the DSL available.+$/,'')
|
25
|
+
routes.sub!(/^(.+routes.draw do\s*)$/, '\1' + line)
|
26
|
+
File.open(filename, "wb") { |file| file.write(routes) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create_controller(controller)
|
31
|
+
filename = File.join(Rails.root, 'app', 'controllers', "#{controller}_controller.rb")
|
32
|
+
if !File.exist?(filename)
|
33
|
+
File.open(filename, "w:utf-8") do |file|
|
34
|
+
file.puts "class #{controller.classify} < ApplicationController"
|
35
|
+
METHODS.each do |method|
|
36
|
+
file.puts
|
37
|
+
file.puts " def #{method}"
|
38
|
+
file.puts
|
39
|
+
file.puts " end"
|
40
|
+
end
|
41
|
+
file.puts
|
42
|
+
file.puts "end"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.create_view_folder(folder)
|
48
|
+
full_path = File.join(Rails.root, 'app', 'views', folder)
|
49
|
+
FileUtils.mkdir_p(full_path)
|
50
|
+
VIEWS.each do |view|
|
51
|
+
File.open(File.join(full_path, "#{view}.html.erb"), "w:utf-8") do |file|
|
52
|
+
file.puts "<h1>This is a temporary page.</h1>"
|
53
|
+
file.puts "<p>To modify this page, edit the template at <code>app/views/#{folder}/#{file}.html.erb</p>"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/lib/ez/schema_modifier.rb
CHANGED
@@ -172,6 +172,7 @@ module EZ
|
|
172
172
|
|
173
173
|
def remove_dead_tables
|
174
174
|
return unless Rails.env.development? || Rails.env.test?
|
175
|
+
return if Dir[File.join(Rails.root, 'db/migrations/*.rb')].entries.any?
|
175
176
|
|
176
177
|
tables_we_need = @spec.keys.map { |model| model.tableize }
|
177
178
|
dead_tables = tables - tables_we_need
|
data/lib/ez/version.rb
CHANGED
data/lib/tasks/ez_tasks.rake
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# Rake::Task["db:migrate"].enhance do
|
2
|
+
# Rake::Task["ez:resources"].invoke
|
3
|
+
# end
|
4
|
+
|
1
5
|
namespace :db do
|
2
6
|
|
3
7
|
namespace :migrate do
|
@@ -18,67 +22,17 @@ namespace :ez do
|
|
18
22
|
|
19
23
|
desc "Generate models.yml if it doesn't exist yet."
|
20
24
|
task :generate_yml do
|
21
|
-
|
22
|
-
unless File.exist?(filename)
|
23
|
-
File.open(filename, "w") do |f|
|
24
|
-
f.puts <<-EOS
|
25
|
-
# Example table for a typical Book model.
|
26
|
-
#
|
27
|
-
# Book
|
28
|
-
# title: string
|
29
|
-
# author_id: integer
|
30
|
-
# price: integer
|
31
|
-
# summary: text
|
32
|
-
# hardcover: boolean
|
33
|
-
#
|
34
|
-
# Indent consistently! Follow the above syntax exactly.
|
35
|
-
# Typical column choices are: string, text, integer, boolean, date, time, and datetime.
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# About Default Values
|
39
|
-
# ----------------------------------------------------
|
40
|
-
# Default column values can be specified like this:
|
41
|
-
# price: integer(0)
|
42
|
-
#
|
43
|
-
# If not specified, Boolean columns always default to false.
|
44
|
-
#
|
45
|
-
#
|
46
|
-
# Convention-Based Defaults:
|
47
|
-
# ----------------------------------------------------
|
48
|
-
# You can omit the column type if it's a string, or if it's obviously an integer column:
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# Book
|
52
|
-
# title
|
53
|
-
# author_id
|
54
|
-
# price: integer
|
55
|
-
# summary: text
|
56
|
-
# hardcover: boolean
|
57
|
-
#
|
58
|
-
# Complete details are in the README file online.
|
59
|
-
#
|
60
|
-
# Have fun!
|
61
|
-
|
62
|
-
EOS
|
63
|
-
end
|
64
|
-
end
|
25
|
+
EZ::DomainModeler.generate_yml
|
65
26
|
end
|
66
27
|
|
67
28
|
desc "Erases all data, and builds all table schema from scratch."
|
68
29
|
task :reset_tables => ['db:drop', :tables] do
|
69
30
|
end
|
70
31
|
|
71
|
-
|
72
32
|
desc "Attempts to update the database schema and model files with minimal data loss."
|
73
33
|
task :tables => [:environment] do
|
74
|
-
|
75
|
-
|
76
|
-
Rake::Task["db:schema:dump"].invoke if (Rails.env.development? || Rails.env.test?)
|
77
|
-
end
|
78
|
-
else
|
79
|
-
Rake::Task["ez:generate_yml"].invoke
|
80
|
-
emit_help_page
|
81
|
-
end
|
34
|
+
emit_help_page unless File.exists?('db/models.yml')
|
35
|
+
EZ::DomainModeler.automigrate
|
82
36
|
end
|
83
37
|
|
84
38
|
def emit_help_page
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ez
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Cohen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: awesome_print
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: hirb
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,7 +75,8 @@ dependencies:
|
|
61
75
|
description: Gem for easier Rails development.
|
62
76
|
email:
|
63
77
|
- cohen.jeff@gmail.com
|
64
|
-
executables:
|
78
|
+
executables:
|
79
|
+
- console
|
65
80
|
extensions: []
|
66
81
|
extra_rdoc_files: []
|
67
82
|
files:
|
@@ -71,10 +86,13 @@ files:
|
|
71
86
|
- LICENSE.txt
|
72
87
|
- README.md
|
73
88
|
- Rakefile
|
89
|
+
- bin/console
|
74
90
|
- ez.gemspec
|
75
91
|
- lib/ez.rb
|
92
|
+
- lib/ez/config.rb
|
76
93
|
- lib/ez/domain_modeler.rb
|
77
94
|
- lib/ez/model.rb
|
95
|
+
- lib/ez/rails_updater.rb
|
78
96
|
- lib/ez/schema_modifier.rb
|
79
97
|
- lib/ez/version.rb
|
80
98
|
- lib/tasks/ez_tasks.rake
|