ez 1.5.0.5 → 1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|