ng_on_rails 0.0.3.1 → 0.0.3.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 +138 -314
- data/lib/generators/ng_on_rails/controller_generator.rb +19 -18
- data/lib/generators/ng_on_rails/jbuilder_generator.rb +43 -0
- data/lib/generators/ng_on_rails/layout_generator.rb +28 -0
- data/lib/generators/ng_on_rails/ng_on_rails_generator.rb +111 -0
- data/lib/generators/ng_on_rails/resource_generator.rb +9 -7
- data/lib/generators/ng_on_rails/scaffold_generator.rb +51 -0
- data/lib/generators/ng_on_rails/templates/app_controller_template.js.coffee +5 -0
- data/lib/generators/ng_on_rails/templates/controller_template.js.erb +32 -32
- data/lib/generators/ng_on_rails/templates/slim/layout_template.html.slim.erb +29 -0
- data/lib/generators/ng_on_rails/templates/views/slim/show.html.erb +2 -7
- data/lib/generators/ng_on_rails/views_generator.rb +53 -64
- data/lib/ng_on_rails/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 242a25464e61e8157c549476b4a36ab9c5b66768
|
4
|
+
data.tar.gz: 48fd4abdc2239a3863371aab1e8a8b8c697654e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 737f3a5cf23dbd0048145872fac1911097a346ed2b6339730c901e3f4796c1067fa855ffcf852ab948a817df28af0577979b6a82702c071084d71411b2ae4a1d
|
7
|
+
data.tar.gz: 63d6d3b6a0f411476a918636d54ad33bb3478043dc2bb5a34a166b172daca20ff71e1dfb37c6ad9cabc1a5886b595911082069046a0ddc4b383a46302d7a1752
|
data/README.md
CHANGED
@@ -6,11 +6,16 @@
|
|
6
6
|
|
7
7
|
*A Rails inspired framework for using AngularJS with Rails*
|
8
8
|
|
9
|
-
|
9
|
+
**This project is in active development. Check back often for updates and be very careful when using with any production app.**
|
10
10
|
|
11
|
-
This
|
11
|
+
This gem aims to standardize and simplify how AngularJS is integrated within a rails application. The hope is to push towards a *convention-over-configuration* approach with using AngularJS with rails.
|
12
12
|
|
13
|
-
|
13
|
+
Key features include:
|
14
|
+
* A [Rails-service](https://github.com/brookisme/ng_on_rails/wiki/Rails-Service) that automatically converts any instance variables to a json object that can be used
|
15
|
+
* [Generators](#ngor_generators) to quickly create angular controllers/services/views/partials
|
16
|
+
* [Directives](#ngor_directives) for rendering views and partials, and other useful view-content
|
17
|
+
|
18
|
+
##### Install it!
|
14
19
|
```
|
15
20
|
# Gemfile
|
16
21
|
gem 'ng_on_rails'
|
@@ -25,65 +30,132 @@ gem 'ng_on_rails'
|
|
25
30
|
//= require_tree .
|
26
31
|
```
|
27
32
|
|
28
|
-
|
29
|
-
|
33
|
+
In your layout below the `javascript_include_tag "application"` load the Rails-service.
|
30
34
|
```html.erb
|
31
35
|
<script>
|
32
36
|
= render( partial: 'angular_app/rails_service', formats: ['js'], locals: { ng_data: ng_data} )
|
33
37
|
</script>
|
34
38
|
```
|
39
|
+
*See our wiki for an detailed layout [example](https://github.com/brookisme/ng_on_rails/wiki/Layouts).*
|
35
40
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
= stylesheet_link_tag "application", :media => "all"
|
47
|
-
== yield :meta
|
48
|
-
== yield :styles
|
49
|
-
|
50
|
-
body ng-app="NgOnRailsApp" ng_controller="AppController as ctrl"
|
51
|
-
.wrapper
|
52
|
-
== yield
|
53
|
-
|
54
|
-
/ scripts
|
55
|
-
= javascript_include_tag "application"
|
56
|
-
script
|
57
|
-
= render( partial: 'angular_app/rails_service', formats: ['js'], locals: { ng_data: ng_data} )
|
58
|
-
== yield :javascripts
|
41
|
+
NgOnRails is now up and running!
|
42
|
+
|
43
|
+
<a name="#ngor_app_note"></a>
|
44
|
+
##### Note: NgOnRailsApp
|
45
|
+
An angular-app, NgOnRailsApp, is automatically created if it doesn't already exsit
|
46
|
+
```javascript
|
47
|
+
# ng_on_rails/app/assets/javascripts/app.js
|
48
|
+
if (!window.NgOnRailsApp){
|
49
|
+
window.NgOnRailsApp = angular.module("NgOnRailsApp", ["ngResource","ngAnimate","ngSanitize"])
|
50
|
+
}
|
59
51
|
```
|
52
|
+
If you want to overide NgOnRailsApp, so you can inject your own providers,
|
53
|
+
Just incldue a app.js file that defines NgOnRailsApp in your own app and load it **before** ng\_on\_rails
|
54
|
+
```javascript
|
55
|
+
# your_app/app/assets/javascripts/angular_app/app.js
|
56
|
+
window.NgOnRailsApp = angular.module("NgOnRailsApp", ["ngResource","ngAnimate","ngSanitize","angular-sortable-view"])
|
60
57
|
|
61
|
-
|
58
|
+
# your_app/app/assets/javascripts/application.js
|
59
|
+
//= require ...
|
60
|
+
//= require angular_app/app.js
|
61
|
+
//= require ng_on_rails
|
62
|
+
//= require tree.
|
62
63
|
```
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
|
65
|
+
I would love feed back (especially on convention choices) and possibly other contributers. Send me a note!
|
66
|
+
|
67
|
+
-----------------------------------------------------------
|
68
|
+
|
69
|
+
### Conventions
|
70
|
+
|
71
|
+
NgOnRails expects that there is an "angular\_app" directory in your javascripts directory containing all of the controllers/directives/services you are going to use. Simalarly, NgOnRails expects that there is an "angular\_app" directory in your views directory containing all the angular-views/partials. Naming/Path conventions follow what one would naturally expect from Rails.
|
72
|
+
|
73
|
+
Example Directory Structure (*In this example the Rails app has 'Page' model*):
|
67
74
|
```
|
68
|
-
|
75
|
+
|-- app/
|
76
|
+
|-- assests/
|
77
|
+
|-- javascripts/
|
78
|
+
|-- angular_app/
|
79
|
+
|-- controllers/
|
80
|
+
|-- app_controller.js
|
81
|
+
|-- pages_controller.js
|
82
|
+
|-- directives/
|
83
|
+
|-- services/
|
84
|
+
|-page.js
|
85
|
+
|- app.js ([optional](#ngor_app_note))
|
86
|
+
|-- views/
|
87
|
+
|-- angular_app/
|
88
|
+
|-- pages/
|
89
|
+
|-- _page.html
|
90
|
+
|-- _pages.html
|
91
|
+
|-- _show.html
|
92
|
+
|-- index.html
|
93
|
+
|-- show.html
|
94
|
+
|-- pages/
|
95
|
+
```
|
96
|
+
|
97
|
+
##### Things to note:
|
98
|
+
* Try to have as little AngularJS as possible outside of my angular_app folder. Assuming there exists a rails "Page" model, handle the views like this:
|
99
|
+
```html
|
100
|
+
# your_app/app/views/pages/index.html
|
101
|
+
<!-- Apart from this render_view directive don't put any other angular in this file -->
|
102
|
+
<div render_view="true" url="pages/index" ng-init="pages=ctrl.rails.pages"></div>
|
103
|
+
|
69
104
|
|
105
|
+
# your_app/app/views/angular_app/pages/show.html
|
106
|
+
<div ng_controller="PagesController as ctrl">
|
107
|
+
<div ng-repeat="page in pages">
|
108
|
+
<div render='true' url='pages/page'>
|
109
|
+
<div ng-show="ctrl.is_editing(page)">...
|
110
|
+
```
|
111
|
+
* In the above, `ctrl.rails` has been set to the Rails service in the AppController
|
112
|
+
* Use the Controller-As syntax! I know there are people who aren't a fan. However in most apps where I am using angular there is a complicated Model structure. I necessarly want to edit all these things on a single page, though spread out through many partials. Controller-As really really helps keep the logic clear.
|
113
|
+
|
114
|
+
These conventions can be easily followed (directories will be generated) if you use the NgOnRails [generators](#ngor_generators)).
|
115
|
+
|
116
|
+
*See [test_app](https://github.com/brookisme/ng_on_rails/tree/master/spec/test_app) for an example of these conventions.*
|
117
|
+
|
118
|
+
-----------------------------------------------------------
|
119
|
+
|
120
|
+
<a name="ngor_generators"></a>
|
121
|
+
### Generators
|
122
|
+
|
123
|
+
You can quickly your project up and running using the NgOnRails generators:
|
124
|
+
* ng_on_rails:layout - generates layout files in your\_app/app/views/layouts/
|
125
|
+
* ng_on_rails:jbuilder - generates jbuilder files in your\_app/app/views/model\_plural\_name/
|
126
|
+
* ng_on_rails:controller - generates an ng-controller in your\_app/app/assests/javascripts/angular\_app/controllers/
|
127
|
+
* ng_on_rails:resource - generates a ng-resource-service in your\_app/app/assests/javascripts/angular\_app/services/
|
128
|
+
* ng_on_rails:views - generates views in your\_app/app/views/angular\_app/model_plural_name/
|
129
|
+
* ng_on_rails:scaffold - all of the above
|
130
|
+
|
131
|
+
Here is a brief overview of many of the options available
|
132
|
+
```
|
133
|
+
$ bundle exec rails g ng_on_rails:scaffold --help
|
70
134
|
|
71
|
-
`ng_on_rails:views` has many options:
|
72
|
-
```
|
73
|
-
$ bundle exec rails g ng_on_rails:views --help
|
74
135
|
Usage:
|
75
|
-
rails generate ng_on_rails:
|
136
|
+
rails generate ng_on_rails:scaffold MODEL_NAME [options]
|
76
137
|
|
77
138
|
Options:
|
78
|
-
[--properties=one two three]
|
79
|
-
[--relationships=one two three]
|
80
|
-
[--format=FORMAT]
|
81
|
-
|
82
|
-
[--render-views], [--no-render-views]
|
83
|
-
|
84
|
-
[--
|
85
|
-
|
86
|
-
[--belongs-to=one two three]
|
139
|
+
[--properties=one two three] # list of properties
|
140
|
+
[--relationships=one two three] # list of relationships. determines has_many/one from singular/plural name
|
141
|
+
[--format=FORMAT] # *** FOR NOW ONLY OFFERS SLIM*** templating engine. defaults to slim. slim, haml, erb
|
142
|
+
# Default: slim
|
143
|
+
[--render-views], [--no-render-views] # Insert render_view directives into rails-views
|
144
|
+
# Default: true
|
145
|
+
[--jbuilder], [--no-jbuilder] # Create jbuilder files the rails-views directory for json
|
146
|
+
[--rails-views], [--no-rails-views] # Insert both render_views and jbuilder files in rails-views
|
147
|
+
[--belongs-to=one two three] # list of models it belongs_to
|
148
|
+
[--overwrite], [--no-overwrite] # overwrite file if it exist
|
149
|
+
[--layout], [--no-layout] # create layout
|
150
|
+
# Default: true
|
151
|
+
[--app-controller], [--no-app-controller] # create app_controller
|
152
|
+
# Default: true
|
153
|
+
[--build], [--no-build] # BUILD as ng_data default
|
154
|
+
# Default: true
|
155
|
+
[--layout-name=LAYOUT_NAME] # name of layout. defaults to 'application', creating the file application.html.<format>
|
156
|
+
# Default: application
|
157
|
+
[--styles], [--no-styles] # add ng_on_rails_styles.css
|
158
|
+
# Default: true
|
87
159
|
```
|
88
160
|
* `--properties` is a list of properties you want in the views. A property looks like `property_name:property_type{opt1+opt2+...}`.
|
89
161
|
* property\_name: (required) name of the property
|
@@ -98,7 +170,6 @@ Options:
|
|
98
170
|
```
|
99
171
|
bundle exec rails g ng_on_rails:views Doc --properties id:number{skip_form+link} name{required} description:textarea{skip_index}
|
100
172
|
```
|
101
|
-
* `--format, --styles` should be self explanatory.
|
102
173
|
* `--render-views=true` will append (creating file if necessary) code to load the angular views to your index and show views in your views directory. For example, your index files becomes:
|
103
174
|
```slim
|
104
175
|
# your_app/app/views/docs/index.html.slim
|
@@ -113,105 +184,36 @@ div ng-init="docs=ctrl.rails.docs" render_view="true" url="docs/index"
|
|
113
184
|
/
|
114
185
|
/
|
115
186
|
```
|
116
|
-
* `--belongs_to`
|
187
|
+
* `--belongs_to` In the controller generator it will will ensure that belongs to relationships are set in the "rest.new()" and "rest.edit()" methods. In the views it will ensure that the correct id's for these models get passed in the right order.
|
188
|
+
* `--styles` Copies a simple NgOnRails stylesheet into your stylesheets directory. This will make the views look slightly nicer. *Note: The generated views are fine without additional frameworks but have been written to use both [bootstrap](http://getbootstrap.com/) and [fontAwesome](http://fortawesome.github.io/Font-Awesome/).*
|
117
189
|
|
118
190
|
##### Test App
|
119
|
-
The [test_app](https://github.com/brookisme/ng_on_rails/tree/master/spec/test_app) serves as an example of how to
|
191
|
+
The [test_app](https://github.com/brookisme/ng_on_rails/tree/master/spec/test_app) serves as an example of how to use these generators. With one minor alteration the test app was generated with the following commands:
|
120
192
|
```
|
193
|
+
$ bundle exec rails g ng_on_rails:layout
|
121
194
|
$ bundle exec rails g ng_on_rails:resource Doc
|
122
195
|
$ bundle exec rails g ng_on_rails:controller Doc
|
123
|
-
$ bundle exec rails g ng_on_rails:
|
196
|
+
$ bundle exec rails g ng_on_rails:jbuilder Doc id name description pages --overwrite=true
|
197
|
+
$ bundle exec rails g ng_on_rails:views Doc --properties id:number{skip_form+link} name{required} description:textarea{skip_index} --relationships pages --rails-views
|
124
198
|
$ bundle exec rails g ng_on_rails:resource Page
|
125
199
|
$ bundle exec rails g ng_on_rails:controller Page --belongs_to Doc
|
126
|
-
$ bundle exec rails g ng_on_rails:
|
200
|
+
$ bundle exec rails g ng_on_rails:jbuilder Page
|
201
|
+
$ bundle exec rails g ng_on_rails:views Page --properties id:number{skip_form+link} order_index:number subject{required} body:textarea{skip_index} --belongs_to Doc --rails-views
|
127
202
|
```
|
128
|
-
|
129
|
-
##### Service: Rails
|
130
|
-
As will be discussed in detail [below](#locals_to_json), NgOnRails provides a Rails-service that can be injected into your Angular Controllers. This service has all your rails variables contained in json. So @page and @pages will get mapped to Rails.page and Rails.pages to be used by your angular app.
|
131
|
-
|
132
|
-
##### Directives: render and render\_view
|
133
|
-
NgOnRails provides you with two directives, `render` for displapying angular partials and `render_view` for displaying angular views. More details [here](#render_directives).
|
134
|
-
|
135
|
-
##### Note: NgOnRailsApp
|
136
|
-
An angular-app, NgOnRailsApp, is automatically created if it doesn't already exsit
|
137
|
-
```javascript
|
138
|
-
# ng_on_rails/app/assets/javascripts/app.js
|
139
|
-
if (!window.NgOnRailsApp){
|
140
|
-
window.NgOnRailsApp = angular.module("NgOnRailsApp", ["ngResource","ngAnimate","ngSanitize"])
|
141
|
-
}
|
203
|
+
or even better, in two lines with the scaffolding short hand:
|
142
204
|
```
|
143
|
-
|
144
|
-
|
145
|
-
```javascript
|
146
|
-
# your_app/app/assets/javascripts/angular_app/app.js
|
147
|
-
window.NgOnRailsApp = angular.module("NgOnRailsApp", ["ngResource","ngAnimate","ngSanitize","angular-sortable-view"])
|
148
|
-
|
149
|
-
# your_app/app/assets/javascripts/application.js
|
150
|
-
//= require ...
|
151
|
-
//= require angular_app/app.js
|
152
|
-
//= require ng_on_rails
|
153
|
-
//= require tree.
|
205
|
+
$ bundle exec rails g ng_on_rails:views Doc --properties id:number{skip_form+link} name{required} description:textarea{skip_index} --relationships pages --rails-views
|
206
|
+
$ bundle exec rails g ng_on_rails:views Page --properties id:number{skip_form+link} order_index:number subject{required} body:textarea{skip_index} --belongs_to Doc --rails-views``
|
154
207
|
```
|
155
208
|
|
156
|
-
I would love feed back (especially on convention choices) and possibly other contributers. Send me a note!
|
157
|
-
|
158
209
|
-----------------------------------------------------------
|
159
210
|
|
160
|
-
|
161
|
-
|
162
|
-
As time goes on generators for angular controllers and services (rails-models) will be added, as well as some view helpers and directives. For the time being however the the gem is rather simple.
|
163
|
-
|
164
|
-
It relies on two pieces of slight magic
|
165
|
-
|
166
|
-
* a "Rails" service that holds all your rails variables. This service automatically turns rails instance variables into json that can be used by Angular. For example the rails instance variable `@pages` will get mapped to `Rails.pages` that can be used by angular
|
167
|
-
```
|
168
|
-
<div ng-repeat="page in Rails.pages">...
|
169
|
-
```
|
170
|
-
To get this work you simply need to load the rails_service.js.erb partial
|
171
|
-
```html.erb
|
172
|
-
<script>
|
173
|
-
= render( partial: 'angular_app/rails_service', formats: ['js'], locals: { ng_data: ng_data} )
|
174
|
-
</script>
|
175
|
-
```
|
176
|
-
"rails_service.js.erb" calls the `locals_to_json` helper method to automatically turn instance variables into json. Here `ng_data` is a local rails variable used to customize how this is converted. This will be discussed in detail [below](#locals_to_json).
|
177
|
-
|
178
|
-
* Your angular views and partials should be placed in your\_app/app/views/angular_app. This solution is discussed in a handfull of places including [here](http://stackoverflow.com/questions/12116476/rails-static-html-template-files-in-the-asset-pipeline-and-caching-in-developmen), but the key parts are:
|
179
|
-
```ruby
|
180
|
-
# routes.rb
|
181
|
-
scope :angular_app do
|
182
|
-
get ':path.html' => 'ng_on_rails#template', constraints: { path: /.+/ }
|
183
|
-
end
|
184
|
-
|
185
|
-
# ng_on_rails_controller.rb
|
186
|
-
def template
|
187
|
-
@path = params[:path]
|
188
|
-
render template: '/angular_app/' + @path, layout: nil
|
189
|
-
end
|
190
|
-
```
|
191
|
-
Now you can then use the ng\_on\_rails directives 'render' and 'render\_view' to load your your angular partials and views in 'your\_app/app/views/angular\_app'.
|
192
|
-
|
193
|
-
#### Conventions
|
194
|
-
|
195
|
-
The [test_app](https://github.com/brookisme/ng_on_rails/tree/master/spec/test_app) serves as an example of the conventions discussed below, but before looking it over read [this](#test_app).
|
196
|
-
|
197
|
-
* Put Angular controllers/directives/... in a folder "angular\_app" in the assets directory. Similarly, as discussed above, the angular views(partials) are placed in a folder "angular\_app" in the views directory
|
198
|
-
```
|
199
|
-
|-- app/
|
200
|
-
|-- assests/
|
201
|
-
|-- javascripts/
|
202
|
-
|-- angular_app/
|
203
|
-
|-- controllers/
|
204
|
-
|-- directives/
|
205
|
-
|-- services/
|
206
|
-
|- app.js
|
207
|
-
|-- views/
|
208
|
-
|-- angular_app/
|
211
|
+
<a name="ngor_directives"></a>
|
212
|
+
### Render Directives
|
209
213
|
|
210
|
-
|
211
|
-
Files should be named/put in folders in the same maner that you would in Rails. For instance, if you have a Page model, you would have a pages_controller.js and a service page.js. Then under views you would have pages/{show.html,index.html,\_page.html,\_form.html,...}.
|
214
|
+
As in Rails partials are prefixed with and underscore ("\_"). Partials should be loaded with the render directive. The 'views' should be loaded with the render\_view directive. The main distinguishing factor between views and partials are if they load a angular controller.
|
212
215
|
|
213
|
-
|
214
|
-
As in rails files prefixed with "\_" are 'partials' and should be loaded with the render directive. The 'views' should be loaded with the render\_view directive. The main distinguishing factor between views and partials are if they load a angular controller. Here are two examples: The first is a 'view', the index view for a Doc model, and the second is partial that displays information on the doc.
|
216
|
+
Here is an example: The first file is a 'view', the index view for a Doc model, and the second is partial that displays information on the doc.
|
215
217
|
```slim
|
216
218
|
# VIEW: your_app/app/views/angular_app/docs/index.html.slim
|
217
219
|
div ng_controller="DocsController as ctrl" ng-init="ctrl.setDocs(docs)"
|
@@ -233,194 +235,16 @@ div ng-bind="doc.description"
|
|
233
235
|
```
|
234
236
|
Note that using distinguishing characterisic of loading the controller via `ng_controller` loading layout is parallel to how views and partials are distinguished in rails.
|
235
237
|
|
236
|
-
|
237
|
-
|
238
|
-
```html
|
239
|
-
# your_app/app/views/pages/index.html
|
240
|
-
<!-- Apart from this render_view directive don't put any other angular in this file -->
|
241
|
-
<div render_view="true" url="pages/index" ng-init="pages=ctrl.rails.pages"></div>
|
242
|
-
|
243
|
-
|
244
|
-
# your_app/app/views/angular_app/pages/show.html
|
245
|
-
<div ng_controller="PagesController as ctrl">
|
246
|
-
<div ng-repeat="page in pages">
|
247
|
-
<div render='true' url='pages/page'>
|
248
|
-
<div ng-show="ctrl.is_editing(page)">...
|
249
|
-
```
|
250
|
-
*In the above, `ctrl.rails` has been set to the Rails service in the AppController*
|
251
|
-
|
252
|
-
* This brings up another point. Use the Controller-As syntax! I know there are people who aren't a fan. However in most apps where I am using angular there is a complicated Model structure. I necessarly want to edit all these things on a single page, though spread out through many partials. Controller-As really really helps keep the logic clear.
|
253
|
-
|
254
|
-
|
255
|
-
#### Angular Services for Rails Models
|
256
|
-
You are going to have a resource-service for each rails model. You can create these with the NgOnRails generator
|
257
|
-
```
|
258
|
-
$ bundle exec rails g ng_on_rails:resource Page
|
259
|
-
```
|
260
|
-
Which creates the following file:
|
261
|
-
```coffeescript
|
262
|
-
# your_app/app/assets/javascripts/angular_app/services/page.js.coffee
|
263
|
-
NgOnRailsApp.factory "Page", ($resource) ->
|
264
|
-
PageResource = $resource "/questions/:id.json", {id: "@id"}, {
|
265
|
-
update:{method: "PUT"}
|
266
|
-
}
|
267
|
-
class Page extends PageResource
|
268
|
-
# place class and instance methods here if you want them.
|
269
|
-
```
|
270
|
-
|
271
|
-
|
272
|
-
#### Angular Controllers for Rails Models
|
273
|
-
Simalarly you are going to have an angular controller for each rails model. A controller that uses the Rails-service and pre-defined REST methods can be generated with
|
274
|
-
```
|
275
|
-
$ bundle exec rails g ng_on_rails:controller Page
|
276
|
-
```
|
277
|
-
The output is below (*Note that I place all the REST methods in a rest object*):
|
278
|
-
|
279
|
-
```coffeescript
|
280
|
-
# your_app/app/assets/javascripts/angular_app/controllers/pages_controller.js.coffee
|
281
|
-
NgOnRailsApp.controller 'PagesController', ($scope,Page,Rails) ->
|
282
|
-
#
|
283
|
-
# CONTROLLER SETUP
|
284
|
-
#
|
285
|
-
ctrl = this
|
286
|
-
ctrl.rails = Rails
|
287
|
-
ctrl.data = {}
|
288
|
-
|
289
|
-
|
290
|
-
#
|
291
|
-
# INITIALIZERS
|
292
|
-
#
|
293
|
-
ctrl.setPage = (page)->
|
294
|
-
ctrl.data.page = page
|
295
|
-
ctrl.setPages = (pages)->
|
296
|
-
ctrl.data.pages = pages
|
297
|
-
|
298
|
-
|
299
|
-
#
|
300
|
-
# REST METHODS
|
301
|
-
#
|
302
|
-
ctrl.rest =
|
303
|
-
index: ->
|
304
|
-
params = {}
|
305
|
-
Page.query(params).$promise.then (pages) ->
|
306
|
-
ctrl.data.pages = pages
|
307
|
-
|
308
|
-
show: (page_id)->
|
309
|
-
Page.get({id: page_id}).$promise.then (page) ->
|
310
|
-
ctrl.data.page = page
|
311
|
-
|
312
|
-
new: ()->
|
313
|
-
ctrl.clear()
|
314
|
-
ctrl.data.activePage = {}
|
315
|
-
ctrl.data.creating_new_page = true
|
316
|
-
|
317
|
-
create: ->
|
318
|
-
if !(ctrl.locked || ctrl.page_form.$error.required)
|
319
|
-
ctrl.locked = true
|
320
|
-
working_page = angular.copy(ctrl.data.activePage)
|
321
|
-
Page.save(
|
322
|
-
working_page,
|
323
|
-
(page)->
|
324
|
-
ctrl.data.pages ||= []
|
325
|
-
ctrl.data.pages.push(page)
|
326
|
-
ctrl.clear()
|
327
|
-
ctrl.locked = false
|
328
|
-
,
|
329
|
-
(error)->
|
330
|
-
console.log("create_error:",error)
|
331
|
-
ctrl.clear()
|
332
|
-
ctrl.locked = false
|
333
|
-
)
|
334
|
-
|
335
|
-
edit: (page) ->
|
336
|
-
ctrl.clear()
|
337
|
-
ctrl.data.activePage = page
|
338
|
-
ctrl.data.editing_page = true
|
339
|
-
|
340
|
-
update: (page)->
|
341
|
-
if !(ctrl.locked || ctrl.page_form.$error.required)
|
342
|
-
ctrl.locked = true
|
343
|
-
page = ctrl.data.activePage unless !!page
|
344
|
-
working_page = angular.extend(angular.copy(page),ctrl.data.activePage)
|
345
|
-
Page.update(
|
346
|
-
working_page,
|
347
|
-
(page)->
|
348
|
-
# success handler
|
349
|
-
ctrl.locked = false
|
350
|
-
,
|
351
|
-
(error)->
|
352
|
-
console.log("update_error:",error)
|
353
|
-
ctrl.locked = false
|
354
|
-
)
|
355
|
-
ctrl.clear()
|
356
|
-
|
357
|
-
delete: (index,page,pages)->
|
358
|
-
Page.delete(
|
359
|
-
page,
|
360
|
-
(page)->
|
361
|
-
pages ||= ctrl.data.pages
|
362
|
-
pages.splice(index,1)
|
363
|
-
,
|
364
|
-
(error)->
|
365
|
-
console.log("delete_error:",error)
|
366
|
-
)
|
367
|
-
ctrl.clear()
|
368
|
-
|
369
|
-
|
370
|
-
#
|
371
|
-
# SCOPE METHODS
|
372
|
-
#
|
373
|
-
ctrl.clear = ->
|
374
|
-
ctrl.data.activePage = null
|
375
|
-
ctrl.data.creating_new_page = false
|
376
|
-
ctrl.data.editing_page = false
|
377
|
-
|
378
|
-
ctrl.is_editing = (page)->
|
379
|
-
(ctrl.data.editing_page && !!page && page.id == ctrl.data.activePage.id) ||
|
380
|
-
(ctrl.data.creating_new_page && !page)
|
381
|
-
|
382
|
-
|
383
|
-
#
|
384
|
-
# PRIVATE METHODS
|
385
|
-
#
|
386
|
-
# => add methods here, not attached to the ctrl object to be used internally
|
387
|
-
#
|
388
|
-
|
389
|
-
|
390
|
-
#
|
391
|
-
# END
|
392
|
-
#
|
393
|
-
return
|
394
|
-
```
|
395
|
-
<a name="locals_to_json"></a>
|
396
|
-
#### Rails variables to Angular-able json.
|
397
|
-
|
398
|
-
As mentioned using the Rails-service you can get access to all your rails variables in angular.
|
399
|
-
```html.erb
|
400
|
-
<script>
|
401
|
-
= render( partial: 'angular_app/rails_service', formats: ['js'], locals: { ng_data: ng_data} )
|
402
|
-
</script>
|
403
|
-
```
|
404
|
-
Here, ng_data is a local rails variable that describes how to create the json:
|
405
|
-
|
406
|
-
* if ng_data is nil all varibles will be converted with `.to_json` ( or if its a string/numeric with .to_s )
|
407
|
-
* if `ng_data['BUILD'].blank?` the default will be to use `.to_json` for conversion.
|
408
|
-
* if `ng_data['BUILD']=true` the default will be to look for a `.json` file in the app/views directory. It will guess the name and path to this file using the name of var. For instance, if we have @page it will look for the the file app/views/pages/page.json.
|
409
|
-
* if `ng_data[var_name].blank?` the conversion will use the default discussed above
|
410
|
-
* if `ng_data[var_name]={ path: 'path/to/file', as: model_name } it will use this info to try and find the build file. For instance, suppose I have a collection of pages called `@admin_pages`. Then `ng_data['admin_pages'] = { path: "pages/pages", as: :pages }` will look for the file app/views/pages/pages.json seting the local variable `pages = @admin_pages`.
|
411
|
-
|
412
|
-
To understand it better look at [ng_on_rails_helper.rb](https://github.com/brookisme/ng_on_rails/blob/master/app/helpers/ng_on_rails_helper.rb).
|
238
|
+
-----------------------------------------------------------
|
413
239
|
|
414
240
|
<a name="test_app"></a>
|
415
|
-
|
241
|
+
### Test App
|
416
242
|
The [test_app](https://github.com/brookisme/ng_on_rails/tree/master/spec/test_app) can be used as an example application. A some details to mention:
|
417
|
-
|
418
243
|
* The DB is Postgres
|
419
244
|
* The (Angular) Views use Slim
|
420
245
|
* The JS uses CoffeeScript (except for _rails_service.js.erb -- where I need access to Rails)
|
421
|
-
* Much of app/views/angular_app & app/assests/javascripts/angular_app has been cut and pasted in from a different
|
422
|
-
|
423
|
-
* Though there is limited CSS but I use both bootstrap and font-awesome
|
246
|
+
* Much of app/views/angular_app & app/assests/javascripts/angular_app has been cut and pasted in from a different
|
247
|
+
* The CSS uses both bootstrap and font-awesome
|
424
248
|
|
425
249
|
|
426
250
|
|
@@ -1,33 +1,34 @@
|
|
1
|
-
require '
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
2
|
module NgOnRails
|
3
|
-
class ControllerGenerator <
|
3
|
+
class ControllerGenerator < NgOnRails::NgOnRailsGenerator
|
4
4
|
desc "Creates NgOnRails-style AngularJS Controller"
|
5
|
-
|
5
|
+
argument :model_name, type: :string, required: false, desc: "model name"
|
6
6
|
|
7
7
|
def self.source_root
|
8
8
|
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def generate_controller
|
12
|
+
if model_name.blank?
|
13
|
+
option_copy_file "#{ControllerGenerator.source_root}/app_controller_template.js.coffee",
|
14
|
+
"app/assets/javascripts/angular_app/controllers/app_controller.js.coffee",
|
15
|
+
"app controller"
|
16
|
+
else
|
17
|
+
option_copy_file "#{ControllerGenerator.source_root}/controller_template.js.erb",
|
18
|
+
"app/assets/javascripts/angular_app/controllers/#{plural_name}_controller.js.coffee",
|
19
|
+
"#{plural_name} controller",
|
20
|
+
true
|
21
|
+
end
|
13
22
|
end
|
14
23
|
|
15
24
|
private
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
options[:belongs_to].map do |a|
|
22
|
-
a.underscore.gsub(" ","")+"_id"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
+
#
|
27
|
+
# View Helpers
|
28
|
+
#
|
26
29
|
|
27
|
-
def
|
28
|
-
|
29
|
-
belongs_to_array.join(",")
|
30
|
-
end
|
30
|
+
def path_to_index_page
|
31
|
+
Rails.application.routes.url_helpers.send("#{plural_name}_path")
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
|
+
module NgOnRails
|
3
|
+
class JbuilderGenerator < NgOnRails::NgOnRailsGenerator
|
4
|
+
desc "Creates jbuilder files in rails-views"
|
5
|
+
argument :model_name, type: :string, required: true, desc: "model name"
|
6
|
+
argument :attributes, type: :array, required: false, desc: "list of attributes in json"
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_index
|
13
|
+
option_create "app/views/#{plural_name}/index.json.jbuilder",
|
14
|
+
"json.partial! '#{plural_name}/#{plural_name}.json', #{plural_name}: @#{plural_name}",
|
15
|
+
"index jbuilder"
|
16
|
+
end
|
17
|
+
def generate_show
|
18
|
+
option_create "app/views/#{plural_name}/show.json.jbuilder",
|
19
|
+
"json.partial! '#{plural_name}/#{resource_name}.json', #{resource_name}: @#{resource_name}",
|
20
|
+
"index jbuilder"
|
21
|
+
end
|
22
|
+
def generate_models
|
23
|
+
option_create "app/views/#{plural_name}/_#{plural_name}.json.jbuilder",
|
24
|
+
"json.array! #{plural_name}, partial: '#{plural_name}/#{resource_name}.json', as: :#{resource_name}",
|
25
|
+
"models jbuilder"
|
26
|
+
end
|
27
|
+
def generate_model
|
28
|
+
option_create "app/views/#{plural_name}/_#{resource_name}.json.jbuilder",
|
29
|
+
"json.extract! #{resource_name} #{attributes_string}",
|
30
|
+
"model jbuilder"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def attributes_string
|
36
|
+
unless attributes.blank?
|
37
|
+
attributes.map{ |attribute|
|
38
|
+
", :#{attribute}"
|
39
|
+
}.join("")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
|
+
module NgOnRails
|
3
|
+
class LayoutGenerator < NgOnRails::NgOnRailsGenerator
|
4
|
+
desc "Creates NgOnRails-style AngularJS layout"
|
5
|
+
|
6
|
+
# arguments
|
7
|
+
class_option :app_controller, type: :boolean, required: false, default: true, desc: "create app_controller"
|
8
|
+
class_option :build, type: :boolean, required: false, default: true, desc: "BUILD as ng_data default"
|
9
|
+
class_option :layout_name, type: :string, required: false, default: "application", desc: "name of layout. defaults to 'application', creating the file application.html.<format>"
|
10
|
+
|
11
|
+
def copy_layout
|
12
|
+
option_template "#{LayoutGenerator.source_root}/#{options[:format]}/layout_template.html.#{options[:format]}.erb",
|
13
|
+
"app/views/layouts/#{options[:layout_name]}.html.#{options[:format]}",
|
14
|
+
"layout file"
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_app_controller
|
18
|
+
if options[:app_controller]
|
19
|
+
option_copy_file "#{LayoutGenerator.source_root}/app_controller_template.js.coffee",
|
20
|
+
"app/assets/javascripts/angular_app/controllers/app_controller.js.coffee",
|
21
|
+
"app controller"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module NgOnRails
|
3
|
+
class NgOnRailsGenerator < Rails::Generators::Base
|
4
|
+
desc "Shared options and methods for NgOnRails Generators"
|
5
|
+
|
6
|
+
class_option :properties, type: :array, required: false, default: [], desc: "list of properties"
|
7
|
+
class_option :relationships, type: :array, required: false, default: [], desc: "list of relationships. determines has_many/one from singular/plural name"
|
8
|
+
class_option :format, type: :string, required: false, default: "slim", desc: "*** FOR NOW ONLY OFFERS SLIM*** templating engine. defaults to slim. slim, haml, erb"
|
9
|
+
class_option :render_views, type: :boolean, required: false, default: true, desc: "Insert render_view directives into rails-views"
|
10
|
+
class_option :jbuilder, type: :boolean, required: false, default: false, desc: "Create jbuilder files the rails-views directory for json"
|
11
|
+
class_option :rails_views, type: :boolean, required: false, default: false, desc: "Insert both render_views and jbuilder files in rails-views"
|
12
|
+
class_option :belongs_to, type: :array, required: false, default: [], desc: "list of models it belongs_to"
|
13
|
+
class_option :overwrite, type: :boolean, required: false, default: false, desc: "overwrite file if it exist"
|
14
|
+
|
15
|
+
def self.source_root
|
16
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def class_name
|
22
|
+
@class_name ||= model_name.classify
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_name
|
26
|
+
@resource_name ||= class_name.underscore
|
27
|
+
end
|
28
|
+
|
29
|
+
def plural_name
|
30
|
+
@plural_name ||= resource_name.pluralize
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# View Helpers
|
35
|
+
#
|
36
|
+
|
37
|
+
def path_to_index_page
|
38
|
+
Rails.application.routes.url_helpers.send("#{plural_name}_path")
|
39
|
+
end
|
40
|
+
|
41
|
+
def belongs_to_array
|
42
|
+
if options[:belongs_to].blank?
|
43
|
+
[]
|
44
|
+
else
|
45
|
+
options[:belongs_to].map do |a|
|
46
|
+
a.underscore.gsub(" ","")+".id"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def belongs_to_parameters
|
52
|
+
unless options[:belongs_to].blank?
|
53
|
+
belongs_to_array.join(",")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def belongs_to_comma
|
58
|
+
unless options[:belongs_to].blank?
|
59
|
+
","
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def belongs_to_values
|
64
|
+
unless options[:belongs_to].blank?
|
65
|
+
belongs_to_array.join(",")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Thor Helpers
|
71
|
+
#
|
72
|
+
|
73
|
+
def option_copy_file from_path, to_path, file_type, template=false
|
74
|
+
if File.exist?(to_path)
|
75
|
+
if options[:overwrite]
|
76
|
+
remove_file(to_path)
|
77
|
+
if template
|
78
|
+
template from_path, to_path
|
79
|
+
else
|
80
|
+
copy_file from_path, to_path
|
81
|
+
end
|
82
|
+
else
|
83
|
+
puts "ERROR: Failed to #{template ? "template" : "copy"} #{file_type || 'file'}. #{to_path} exists. Delete file or use the --overwrite=true option when generating the layout"
|
84
|
+
end
|
85
|
+
else
|
86
|
+
if template
|
87
|
+
template from_path, to_path
|
88
|
+
else
|
89
|
+
copy_file from_path, to_path
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def option_template from_path, to_path, file_type
|
95
|
+
option_copy_file from_path, to_path, file_type, true
|
96
|
+
end
|
97
|
+
|
98
|
+
def option_create file_path, content, file_type
|
99
|
+
if File.exist?(file_path)
|
100
|
+
if options[:overwrite]
|
101
|
+
remove_file(file_path)
|
102
|
+
create_file file_path, content
|
103
|
+
else
|
104
|
+
puts "ERROR: Failed to create #{file_type || 'file'}. #{file_path} exists. Delete file or use the --overwrite=true option when generating the layout"
|
105
|
+
end
|
106
|
+
else
|
107
|
+
create_file file_path, content
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
2
|
module NgOnRails
|
3
|
-
class ResourceGenerator <
|
3
|
+
class ResourceGenerator < NgOnRails::NgOnRailsGenerator
|
4
4
|
desc "Creates NgOnRails-style AngularJS Resource Service"
|
5
|
-
|
6
|
-
def self.source_root
|
7
|
-
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
8
|
-
end
|
5
|
+
argument :model_name, type: :string, required: true, desc: "model name"
|
9
6
|
|
10
7
|
def generate_layout
|
11
|
-
|
8
|
+
option_template "#{ResourceGenerator.source_root}/resource_template.js.erb",
|
9
|
+
"app/assets/javascripts/angular_app/services/#{resource_name}.js.coffee",
|
10
|
+
"#{resource_name} resource"
|
12
11
|
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
13
15
|
end
|
14
16
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
|
+
module NgOnRails
|
3
|
+
class ScaffoldGenerator < NgOnRails::NgOnRailsGenerator
|
4
|
+
desc "Creates NgOnRails-style AngularJS Views"
|
5
|
+
|
6
|
+
argument :model_name, type: :string, required: true, desc: "required"
|
7
|
+
class_option :layout, type: :boolean, required: false, default: true, desc: "create layout"
|
8
|
+
# layout generator
|
9
|
+
class_option :app_controller, type: :boolean, required: false, default: true, desc: "create app_controller"
|
10
|
+
class_option :build, type: :boolean, required: false, default: true, desc: "BUILD as ng_data default"
|
11
|
+
class_option :layout_name, type: :string, required: false, default: "application", desc: "name of layout. defaults to 'application', creating the file application.html.<format>"
|
12
|
+
# views generator
|
13
|
+
class_option :styles, type: :boolean, required: false, default: true, desc: "add ng_on_rails_styles.css"
|
14
|
+
|
15
|
+
def generate_layout
|
16
|
+
if options[:layout]
|
17
|
+
generate "ng_on_rails:layout #{options_string}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def generate_resource
|
21
|
+
generate "ng_on_rails:resource #{model_name} #{options_string}"
|
22
|
+
end
|
23
|
+
def generate_controller
|
24
|
+
generate "ng_on_rails:controller #{model_name} #{options_string}"
|
25
|
+
end
|
26
|
+
def generate_views
|
27
|
+
generate "ng_on_rails:views #{model_name} #{options_string}"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def options_string
|
33
|
+
if @options_string.nil?
|
34
|
+
@options_string = ""
|
35
|
+
options.each do |option|
|
36
|
+
unless option[1].blank?
|
37
|
+
@options_string += " --#{option[0]}"
|
38
|
+
if option[1].is_a?(Array)
|
39
|
+
option[1].each do |opt_value|
|
40
|
+
@options_string += " #{opt_value}"
|
41
|
+
end
|
42
|
+
else
|
43
|
+
@options_string += " #{option[1]}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
@options_string
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -10,8 +10,8 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
10
10
|
#
|
11
11
|
# INITIALIZERS
|
12
12
|
#
|
13
|
-
ctrl.set<%="#{class_name}"%> = (<%="#{
|
14
|
-
ctrl.data.<%="#{
|
13
|
+
ctrl.set<%="#{class_name}"%> = (<%="#{resource_name}"%>)->
|
14
|
+
ctrl.data.<%="#{resource_name}"%> = <%="#{resource_name}"%>
|
15
15
|
ctrl.set<%="#{class_name.pluralize}"%> = (<%="#{plural_name}"%>)->
|
16
16
|
ctrl.data.<%="#{plural_name}"%> = <%="#{plural_name}"%>
|
17
17
|
|
@@ -25,14 +25,14 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
25
25
|
<%="#{class_name}"%>.query(params).$promise.then (<%="#{plural_name}"%>) ->
|
26
26
|
ctrl.data.<%="#{plural_name}"%> = <%="#{plural_name}"%>
|
27
27
|
|
28
|
-
show: (<%="#{
|
29
|
-
<%="#{class_name}"%>.get({id: <%="#{
|
30
|
-
ctrl.data.<%="#{
|
28
|
+
show: (<%="#{resource_name}"%>_id)->
|
29
|
+
<%="#{class_name}"%>.get({id: <%="#{resource_name}"%>_id}).$promise.then (<%="#{resource_name}"%>) ->
|
30
|
+
ctrl.data.<%="#{resource_name}"%> = <%="#{resource_name}"%>
|
31
31
|
|
32
32
|
new: (<%=belongs_to_parameters%>)->
|
33
33
|
ctrl.clear()
|
34
34
|
ctrl.data.active<%="#{class_name}"%> = {}
|
35
|
-
ctrl.data.creating_new_<%="#{
|
35
|
+
ctrl.data.creating_new_<%="#{resource_name}"%> = true
|
36
36
|
<%
|
37
37
|
belongs_to_array.each do |relationship|
|
38
38
|
%>ctrl.data.active<%="#{class_name}"%>.<%= relationship%> = <%= relationship %>
|
@@ -41,14 +41,14 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
41
41
|
%>
|
42
42
|
|
43
43
|
create: ->
|
44
|
-
if !(ctrl.locked || ctrl.<%="#{
|
44
|
+
if !(ctrl.locked || ctrl.<%="#{resource_name}"%>_form.$error.required)
|
45
45
|
ctrl.locked = true
|
46
|
-
working_<%="#{
|
46
|
+
working_<%="#{resource_name}"%> = angular.copy(ctrl.data.active<%="#{class_name}"%>)
|
47
47
|
<%="#{class_name}"%>.save(
|
48
|
-
working_<%="#{
|
49
|
-
(<%="#{
|
48
|
+
working_<%="#{resource_name}"%>,
|
49
|
+
(<%="#{resource_name}"%>)->
|
50
50
|
ctrl.data.<%="#{plural_name}"%> ||= []
|
51
|
-
ctrl.data.<%="#{plural_name}"%>.push(<%="#{
|
51
|
+
ctrl.data.<%="#{plural_name}"%>.push(<%="#{resource_name}"%>)
|
52
52
|
ctrl.clear()
|
53
53
|
ctrl.locked = false
|
54
54
|
,
|
@@ -58,11 +58,11 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
58
58
|
ctrl.locked = false
|
59
59
|
)
|
60
60
|
|
61
|
-
edit: (<%="#{
|
61
|
+
edit: (<%="#{resource_name}"%><%=belongs_to_comma%><%=belongs_to_parameters%>) ->
|
62
62
|
ctrl.clear()
|
63
|
-
ctrl.data.active<%="#{class_name}"%> = <%="#{
|
64
|
-
ctrl.data.editing_<%="#{
|
65
|
-
<%="#{
|
63
|
+
ctrl.data.active<%="#{class_name}"%> = <%="#{resource_name}"%>
|
64
|
+
ctrl.data.editing_<%="#{resource_name}"%> = true
|
65
|
+
<%="#{resource_name}"%>.is_displayed = false
|
66
66
|
<%
|
67
67
|
belongs_to_array.each do |relationship|
|
68
68
|
%>ctrl.data.active<%="#{class_name}"%>.<%= relationship%> = <%= relationship %>
|
@@ -70,14 +70,14 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
70
70
|
end
|
71
71
|
%>
|
72
72
|
|
73
|
-
update: (<%="#{
|
74
|
-
if !(ctrl.locked || ctrl.<%="#{
|
73
|
+
update: (<%="#{resource_name}"%>)->
|
74
|
+
if !(ctrl.locked || ctrl.<%="#{resource_name}"%>_form.$error.required)
|
75
75
|
ctrl.locked = true
|
76
|
-
<%="#{
|
77
|
-
working_<%="#{
|
76
|
+
<%="#{resource_name}"%> = ctrl.data.active<%="#{class_name}"%> unless !!<%="#{resource_name}"%>
|
77
|
+
working_<%="#{resource_name}"%> = angular.extend(angular.copy(<%="#{resource_name}"%>),ctrl.data.active<%="#{class_name}"%>)
|
78
78
|
<%="#{class_name}"%>.update(
|
79
|
-
working_<%="#{
|
80
|
-
(<%="#{
|
79
|
+
working_<%="#{resource_name}"%>,
|
80
|
+
(<%="#{resource_name}"%>)->
|
81
81
|
# success handler
|
82
82
|
ctrl.locked = false
|
83
83
|
,
|
@@ -87,15 +87,15 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
87
87
|
)
|
88
88
|
ctrl.clear()
|
89
89
|
|
90
|
-
delete: (index,<%="#{
|
90
|
+
delete: (index,<%="#{resource_name}"%>,<%="#{plural_name}"%>)->
|
91
91
|
<%="#{class_name}"%>.delete(
|
92
|
-
<%="#{
|
93
|
-
(<%="#{
|
92
|
+
<%="#{resource_name}"%>,
|
93
|
+
(<%="#{resource_name}"%>)->
|
94
94
|
<%="#{plural_name}"%> ||= ctrl.data.<%="#{plural_name}"%>
|
95
95
|
if !!<%="#{plural_name}"%>
|
96
96
|
<%="#{plural_name}"%>.splice(index,1)
|
97
97
|
else
|
98
|
-
window.location.href =
|
98
|
+
window.location.href = "<%= path_to_index_page %>"
|
99
99
|
,
|
100
100
|
(error)->
|
101
101
|
console.log("delete_error:",error)
|
@@ -108,15 +108,15 @@ NgOnRailsApp.controller '<%="#{class_name.pluralize}"%>Controller', ($scope,<%="
|
|
108
108
|
#
|
109
109
|
ctrl.clear = (doc)->
|
110
110
|
ctrl.data.active<%="#{class_name}"%> = null
|
111
|
-
ctrl.data.creating_new_<%="#{
|
112
|
-
ctrl.data.editing_<%="#{
|
111
|
+
ctrl.data.creating_new_<%="#{resource_name}"%> = false
|
112
|
+
ctrl.data.editing_<%="#{resource_name}"%> = false
|
113
113
|
|
114
|
-
ctrl.is_editing = (<%="#{
|
115
|
-
(ctrl.data.editing_<%="#{
|
116
|
-
(ctrl.data.creating_new_<%="#{
|
114
|
+
ctrl.is_editing = (<%="#{resource_name}"%>)->
|
115
|
+
(ctrl.data.editing_<%="#{resource_name}"%> && !!<%="#{resource_name}"%> && <%="#{resource_name}"%>.id == ctrl.data.active<%="#{class_name}"%>.id) ||
|
116
|
+
(ctrl.data.creating_new_<%="#{resource_name}"%> && !<%="#{resource_name}"%>)
|
117
117
|
|
118
|
-
ctrl.toggleDisplay = (<%="#{
|
119
|
-
<%="#{
|
118
|
+
ctrl.toggleDisplay = (<%="#{resource_name}"%>)->
|
119
|
+
<%="#{resource_name}"%>.is_displayed = !<%="#{resource_name}"%>.is_displayed
|
120
120
|
|
121
121
|
#
|
122
122
|
# PRIVATE METHODS
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
/
|
3
|
+
/ NgOnRails: starter-layout
|
4
|
+
/
|
5
|
+
- ng_data = {}
|
6
|
+
<%
|
7
|
+
if options[:build]
|
8
|
+
%>- ng_data['BUILD'] = true<%
|
9
|
+
end
|
10
|
+
%>
|
11
|
+
|
12
|
+
doctype html
|
13
|
+
html
|
14
|
+
head
|
15
|
+
title NgOnRails | TestApp
|
16
|
+
= csrf_meta_tags
|
17
|
+
= stylesheet_link_tag "application", :media => "all"
|
18
|
+
== yield :meta
|
19
|
+
== yield :styles
|
20
|
+
|
21
|
+
body ng-app="NgOnRailsApp" ng_controller="AppController as ctrl"
|
22
|
+
.wrapper
|
23
|
+
== yield
|
24
|
+
|
25
|
+
/ scripts
|
26
|
+
= javascript_include_tag "application"
|
27
|
+
script
|
28
|
+
= render( partial: 'angular_app/rails_service', formats: ['js'], locals: { ng_data: ng_data} )
|
29
|
+
== yield :javascripts
|
@@ -17,19 +17,14 @@ div ng_controller="<%= class_name.pluralize %>Controller as ctrl" ng-init="ctrl.
|
|
17
17
|
button.btn.btn-default confirm="Do you really want to delete <%= resource_name %>: '{{<%= resource_name %>.<%=@name_rep %>}}'?" action="ctrl.rest.delete($index,<%= resource_name %>)"
|
18
18
|
i.fa.fa-remove.fa-lg.danger
|
19
19
|
span.ilabel delete
|
20
|
+
a.btn.btn-default href="<%= path_to_index_page %>" <%= plural_name %> list
|
20
21
|
|
21
22
|
.formbox ng-show='ctrl.is_editing(<%= resource_name %>)'
|
22
23
|
div render="true" url="<%= plural_name %>/form"
|
23
|
-
|
24
24
|
<%
|
25
25
|
options[:relationships].each do |relationship|
|
26
|
-
if is_plural?(relationship)
|
27
|
-
relationship_page = "index"
|
28
|
-
else
|
29
|
-
relationship_page = "show"
|
30
|
-
end
|
31
26
|
%>
|
32
|
-
div render_view="true" url="<%= relationship
|
27
|
+
div render_view="true" url="<%= relationship_url(relationship) %>" ng-init="<%= relationship %>=<%= resource_name %>.<%= relationship %>"
|
33
28
|
<%
|
34
29
|
end
|
35
30
|
%>
|
@@ -1,36 +1,32 @@
|
|
1
|
-
require '
|
1
|
+
require File.join(File.dirname(__FILE__), 'ng_on_rails_generator')
|
2
2
|
module NgOnRails
|
3
|
-
class ViewsGenerator <
|
3
|
+
class ViewsGenerator < NgOnRails::NgOnRailsGenerator
|
4
4
|
desc "Creates NgOnRails-style AngularJS Views"
|
5
5
|
|
6
6
|
# arguments
|
7
7
|
argument :model_name, type: :string, required: true, desc: "required"
|
8
|
-
class_option :properties, type: :array, required: false, default: [], desc: "list of properties"
|
9
|
-
class_option :relationships, type: :array, required: false, default: [], desc: "list of relationships. determines has_many/one from singular/plural name"
|
10
|
-
class_option :format, type: :string, required: false, default: "slim", desc: "*** FOR NOW ONLY OFFERS SLIM*** templating engine. defaults to slim. slim, haml, erb"
|
11
|
-
class_option :render_views, type: :boolean, required: false, default: true, desc: "Insert render_view directives into rails-views"
|
12
8
|
class_option :styles, type: :boolean, required: false, default: true, desc: "add ng_on_rails_styles.css"
|
13
|
-
class_option :belongs_to, type: :array, required: false, default: [], desc: "list of models it belongs_to"
|
14
9
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
"
|
22
|
-
|
23
|
-
"app/views/angular_app/#{plural_name}/
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
"
|
28
|
-
|
29
|
-
"app/views/angular_app/#{plural_name}/_#{resource_name}.html.#{options[:format]}"
|
10
|
+
def generate_views
|
11
|
+
option_template "#{ViewsGenerator.source_root}/views/#{options[:format]}/index.html.erb",
|
12
|
+
"app/views/angular_app/#{plural_name}/index.html.#{options[:format]}",
|
13
|
+
"index view"
|
14
|
+
option_template "#{ViewsGenerator.source_root}/views/#{options[:format]}/show.html.erb",
|
15
|
+
"app/views/angular_app/#{plural_name}/show.html.#{options[:format]}",
|
16
|
+
"show view"
|
17
|
+
option_template "#{ViewsGenerator.source_root}/views/#{options[:format]}/_show.html.erb",
|
18
|
+
"app/views/angular_app/#{plural_name}/_show.html.#{options[:format]}",
|
19
|
+
"_show partial"
|
20
|
+
option_template "#{ViewsGenerator.source_root}/views/#{options[:format]}/_form.html.erb",
|
21
|
+
"app/views/angular_app/#{plural_name}/_form.html.#{options[:format]}",
|
22
|
+
"_form partial"
|
23
|
+
option_template "#{ViewsGenerator.source_root}/views/#{options[:format]}/_model.html.erb",
|
24
|
+
"app/views/angular_app/#{plural_name}/_#{resource_name}.html.#{options[:format]}",
|
25
|
+
"_#{resource_name} partial"
|
30
26
|
end
|
31
27
|
|
32
28
|
def create_render_views_files
|
33
|
-
if
|
29
|
+
if options[:render_views] || options[:rails_views]
|
34
30
|
unless File.exist?(index_path)
|
35
31
|
puts "File[ #{index_path} ] does not exist. creating file"
|
36
32
|
create_file index_path, '/ File created with NgOnRails view generator'
|
@@ -43,14 +39,33 @@ module NgOnRails
|
|
43
39
|
end
|
44
40
|
end
|
45
41
|
|
42
|
+
def create_jbuilder_files
|
43
|
+
if options[:render_views] || options[:rails_views]
|
44
|
+
unless File.exist?(index_path)
|
45
|
+
puts "File[ #{index_path} ] does not exist. creating file"
|
46
|
+
create_file index_path, '/ File created with NgOnRails view generator'
|
47
|
+
end
|
48
|
+
|
49
|
+
unless File.exist?(show_path)
|
50
|
+
puts "File[ #{show_path} ] does not exist. creating file"
|
51
|
+
create_file show_path, '/ File created with NgOnRails view generator'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
46
55
|
|
47
56
|
def insert_render_views
|
48
|
-
if
|
57
|
+
if options[:render_views] || options[:rails_views]
|
49
58
|
append_file index_path, render_index_view_template
|
50
59
|
append_file show_path, render_show_view_template
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
63
|
+
def generate_jbuilder_files
|
64
|
+
if options[:jbuilder] || options[:rails_views]
|
65
|
+
generate "ng_on_rails:jbuilder #{class_name} #{jbuilder_attributes} --overwrite=#{options[:overwrite]}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
54
69
|
def add_css
|
55
70
|
if options[:styles]
|
56
71
|
styles_path = "app/assets/stylesheets/ng_on_rails_styles.css"
|
@@ -62,18 +77,6 @@ module NgOnRails
|
|
62
77
|
end
|
63
78
|
|
64
79
|
private
|
65
|
-
|
66
|
-
def class_name
|
67
|
-
@class_name ||= model_name.classify
|
68
|
-
end
|
69
|
-
|
70
|
-
def resource_name
|
71
|
-
@resource_name ||= class_name.underscore
|
72
|
-
end
|
73
|
-
|
74
|
-
def plural_name
|
75
|
-
@plural_name ||= resource_name.pluralize
|
76
|
-
end
|
77
80
|
|
78
81
|
def args arg_string
|
79
82
|
parts = arg_string.split("{")
|
@@ -110,6 +113,10 @@ module NgOnRails
|
|
110
113
|
}
|
111
114
|
end
|
112
115
|
|
116
|
+
def is_plural? string
|
117
|
+
string.pluralize == string
|
118
|
+
end
|
119
|
+
|
113
120
|
#
|
114
121
|
# VIEW HELPERS
|
115
122
|
#
|
@@ -126,34 +133,8 @@ module NgOnRails
|
|
126
133
|
end
|
127
134
|
end
|
128
135
|
|
129
|
-
def
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
def is_plural? string
|
134
|
-
string.pluralize == string
|
135
|
-
end
|
136
|
-
|
137
|
-
def belongs_to_array
|
138
|
-
if options[:belongs_to].blank?
|
139
|
-
[]
|
140
|
-
else
|
141
|
-
options[:belongs_to].map do |a|
|
142
|
-
a.underscore.gsub(" ","")+".id"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def belongs_to_comma
|
148
|
-
unless options[:belongs_to].blank?
|
149
|
-
","
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def belongs_to_values
|
154
|
-
unless options[:belongs_to].blank?
|
155
|
-
belongs_to_array.join(",")
|
156
|
-
end
|
136
|
+
def relationship_url relationship
|
137
|
+
"#{relationship.pluralize}/#{is_plural?(relationship) ? 'index' : 'show' }"
|
157
138
|
end
|
158
139
|
|
159
140
|
#
|
@@ -168,6 +149,14 @@ module NgOnRails
|
|
168
149
|
@show_path ||= "app/views/#{plural_name}/show.html.#{options[:format]}"
|
169
150
|
end
|
170
151
|
|
152
|
+
def jbuilder_attributes
|
153
|
+
(
|
154
|
+
options[:properties].map{ |prop| "#{prop.split("{")[0].split(":")[0]}" } |
|
155
|
+
options[:belongs_to].map{ |model| "#{model}_id" } |
|
156
|
+
options[:relationships]
|
157
|
+
).join(" ")
|
158
|
+
end
|
159
|
+
|
171
160
|
def render_index_view_template
|
172
161
|
if options[:format]=="erb"
|
173
162
|
puts "ERB format not yet added"
|
data/lib/ng_on_rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ng_on_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3.
|
4
|
+
version: 0.0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brookie Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: angularjs-rails
|
@@ -98,9 +98,15 @@ files:
|
|
98
98
|
- app/views/angular_app/_rails_service.js.erb
|
99
99
|
- config/routes.rb
|
100
100
|
- lib/generators/ng_on_rails/controller_generator.rb
|
101
|
+
- lib/generators/ng_on_rails/jbuilder_generator.rb
|
102
|
+
- lib/generators/ng_on_rails/layout_generator.rb
|
103
|
+
- lib/generators/ng_on_rails/ng_on_rails_generator.rb
|
101
104
|
- lib/generators/ng_on_rails/resource_generator.rb
|
105
|
+
- lib/generators/ng_on_rails/scaffold_generator.rb
|
106
|
+
- lib/generators/ng_on_rails/templates/app_controller_template.js.coffee
|
102
107
|
- lib/generators/ng_on_rails/templates/controller_template.js.erb
|
103
108
|
- lib/generators/ng_on_rails/templates/resource_template.js.erb
|
109
|
+
- lib/generators/ng_on_rails/templates/slim/layout_template.html.slim.erb
|
104
110
|
- lib/generators/ng_on_rails/templates/styles_template.css
|
105
111
|
- lib/generators/ng_on_rails/templates/views/slim/_form.html.erb
|
106
112
|
- lib/generators/ng_on_rails/templates/views/slim/_model.html.erb
|