abyme 0.2.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 776eb1dba6863a03c497dffdb3661ea4da1f65bef529e13e405b7d93f5e815eb
4
- data.tar.gz: 3b3109cd85a1f36cf3b105c1f6b615eebcd9a39420bfd61eec099735ede9f7e3
3
+ metadata.gz: fb0f45e02d147c46725a521f0e789998a6c99172333daa039eb5cd0544805c52
4
+ data.tar.gz: f849cda4209753325ecbb737683b510c19f52fb22ac2aa72e095e67c56d5b24f
5
5
  SHA512:
6
- metadata.gz: 333f517957310246619b2ee2c99d3b0f23f8717225520e974905d0cb8164b5b75bfce832ea1a174f1e0baef0c256d4bad1342189191cd20c4e1689529c4a08b5
7
- data.tar.gz: bb44bb23f4c9551a850d8f554af27578537a781023e905a2db391b64943b838f65fffb33a1b216df778b5a232570821567b9b4beacf4d5285dc32cc623d688f9
6
+ metadata.gz: a091fd6a3a798accdcc60a119e7b435d72ce553aea6896e041583d6df65d64157e1511031bad28a8d5b9042c2df3c3501400819cf3791eda7c2ae53618f776e5
7
+ data.tar.gz: f92d9395baad0cfa1a561a9c7936c9856b4b5049c5821040fbdb73aa55c9d444c9de2d5b7bdd59d70ce90e665967782311c9ba85250204f41d78bed644a24753
data/.DS_Store CHANGED
Binary file
@@ -0,0 +1,60 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: build
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Set up Ruby
23
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
24
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
25
+ # uses: ruby/setup-ruby@v1
26
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
27
+ with:
28
+ ruby-version: 2.6
29
+ - name: Install sqlite headers
30
+ run: |
31
+ sudo apt-get update
32
+ sudo apt-get install libsqlite3-dev
33
+
34
+ - name: Install dependencies
35
+ run: bundle install
36
+
37
+ - name: Prepare Database
38
+ run: bundle exec rails db:create db:migrate
39
+ env:
40
+ DB_CONNECTION: sqlite
41
+ DB_DATABASE: db/test.sqlite3
42
+ RAILS_ENV: test
43
+
44
+ - name: Run tests
45
+ run: bundle exec rake
46
+ env:
47
+ DB_CONNECTION: sqlite
48
+ DB_DATABASE: db/test.sqlite3
49
+ RAILS_ENV: test
50
+
51
+ - name: Coveralls
52
+ uses: coverallsapp/github-action@master
53
+ with:
54
+ github-token: ${{ secrets.GITHUB_TOKEN }}
55
+
56
+ - name: Create Coverage Artifact
57
+ uses: actions/upload-artifact@v2
58
+ with:
59
+ name: code-coverage
60
+ path: coverage/
data/.gitignore CHANGED
@@ -11,3 +11,13 @@ yarn-error.log
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+ node_modules
15
+
16
+ # Dummy app
17
+ spec/dummy/db/*.sqlite3
18
+ spec/dummy/db/*.sqlite3-journal
19
+ spec/dummy/db/log/*.log
20
+ spec/dummy/log/
21
+ spec/dummy/tmp/
22
+ spec/dummy/.sass-cache
23
+ spec/dummy/public
data/.rspec CHANGED
@@ -1,3 +1 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
1
+ --require rails_helper
data/.simplecov ADDED
File without changes
data/CHANGELOG.md ADDED
@@ -0,0 +1,93 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased](https://github.com/bear-in-mind/abyme/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.2.4...HEAD)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Bump nokogiri from 1.10.10 to 1.11.1 [\#22](https://github.com/bear-in-mind/abyme/pull/22) ([dependabot[bot]](https://github.com/apps/dependabot))
10
+ - Solved JS compile bug [\#19](https://github.com/bear-in-mind/abyme/pull/19) ([bear-in-mind](https://github.com/bear-in-mind))
11
+
12
+ ## [v0.2.4](https://github.com/bear-in-mind/abyme/tree/v0.2.4) (2020-10-18)
13
+
14
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.2.3...v0.2.4)
15
+
16
+ **Merged pull requests:**
17
+
18
+ - Abymebuilder doc [\#18](https://github.com/bear-in-mind/abyme/pull/18) ([ghbozz](https://github.com/ghbozz))
19
+ - Last fix [\#17](https://github.com/bear-in-mind/abyme/pull/17) ([bear-in-mind](https://github.com/bear-in-mind))
20
+ - Drop demo [\#16](https://github.com/bear-in-mind/abyme/pull/16) ([bear-in-mind](https://github.com/bear-in-mind))
21
+ - Coveralls [\#15](https://github.com/bear-in-mind/abyme/pull/15) ([bear-in-mind](https://github.com/bear-in-mind))
22
+ - changing action name [\#14](https://github.com/bear-in-mind/abyme/pull/14) ([bear-in-mind](https://github.com/bear-in-mind))
23
+ - fixing button default text when auto mode [\#13](https://github.com/bear-in-mind/abyme/pull/13) ([ghbozz](https://github.com/ghbozz))
24
+ - travis and rake update [\#12](https://github.com/bear-in-mind/abyme/pull/12) ([bear-in-mind](https://github.com/bear-in-mind))
25
+ - Autonomous Spec [\#11](https://github.com/bear-in-mind/abyme/pull/11) ([bear-in-mind](https://github.com/bear-in-mind))
26
+
27
+ ## [v0.2.3](https://github.com/bear-in-mind/abyme/tree/v0.2.3) (2020-10-15)
28
+
29
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.2.2...v0.2.3)
30
+
31
+ ## [v0.2.2](https://github.com/bear-in-mind/abyme/tree/v0.2.2) (2020-10-15)
32
+
33
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.2.1...v0.2.2)
34
+
35
+ **Merged pull requests:**
36
+
37
+ - Dummy app setup \(incomplete\) [\#10](https://github.com/bear-in-mind/abyme/pull/10) ([bear-in-mind](https://github.com/bear-in-mind))
38
+
39
+ ## [v0.2.1](https://github.com/bear-in-mind/abyme/tree/v0.2.1) (2020-10-15)
40
+
41
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/0.2.0...v0.2.1)
42
+
43
+ **Merged pull requests:**
44
+
45
+ - fix partial path [\#9](https://github.com/bear-in-mind/abyme/pull/9) ([ghbozz](https://github.com/ghbozz))
46
+
47
+ ## [0.2.0](https://github.com/bear-in-mind/abyme/tree/0.2.0) (2020-10-14)
48
+
49
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.2.0...0.2.0)
50
+
51
+ **Merged pull requests:**
52
+
53
+ - End of doc [\#8](https://github.com/bear-in-mind/abyme/pull/8) ([bear-in-mind](https://github.com/bear-in-mind))
54
+
55
+ ## [v0.2.0](https://github.com/bear-in-mind/abyme/tree/v0.2.0) (2020-10-14)
56
+
57
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/0.1.3...v0.2.0)
58
+
59
+ **Merged pull requests:**
60
+
61
+ - limit & min count options [\#7](https://github.com/bear-in-mind/abyme/pull/7) ([ghbozz](https://github.com/ghbozz))
62
+ - Documentation end [\#6](https://github.com/bear-in-mind/abyme/pull/6) ([bear-in-mind](https://github.com/bear-in-mind))
63
+ - add limit feature [\#5](https://github.com/bear-in-mind/abyme/pull/5) ([ghbozz](https://github.com/ghbozz))
64
+
65
+ ## [0.1.3](https://github.com/bear-in-mind/abyme/tree/0.1.3) (2020-10-13)
66
+
67
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.1.2...0.1.3)
68
+
69
+ ## [v0.1.2](https://github.com/bear-in-mind/abyme/tree/v0.1.2) (2020-10-13)
70
+
71
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/0.1.1...v0.1.2)
72
+
73
+ **Merged pull requests:**
74
+
75
+ - basic lifecycle events [\#4](https://github.com/bear-in-mind/abyme/pull/4) ([ghbozz](https://github.com/ghbozz))
76
+
77
+ ## [0.1.1](https://github.com/bear-in-mind/abyme/tree/0.1.1) (2020-10-12)
78
+
79
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/v0.1.1...0.1.1)
80
+
81
+ ## [v0.1.1](https://github.com/bear-in-mind/abyme/tree/v0.1.1) (2020-10-12)
82
+
83
+ [Full Changelog](https://github.com/bear-in-mind/abyme/compare/9b99709cd8f84e9401adb8ba6f59f0074e2f416b...v0.1.1)
84
+
85
+ **Merged pull requests:**
86
+
87
+ - Gem Content [\#3](https://github.com/bear-in-mind/abyme/pull/3) ([bear-in-mind](https://github.com/bear-in-mind))
88
+ - install generator for stimulus init setup [\#2](https://github.com/bear-in-mind/abyme/pull/2) ([ghbozz](https://github.com/ghbozz))
89
+ - Update rake requirement from ~\> 10.0 to ~\> 13.0 [\#1](https://github.com/bear-in-mind/abyme/pull/1) ([dependabot[bot]](https://github.com/apps/dependabot))
90
+
91
+
92
+
93
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile.lock CHANGED
@@ -1,26 +1,209 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abyme (0.1.0)
4
+ abyme (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ actioncable (6.0.3.4)
10
+ actionpack (= 6.0.3.4)
11
+ nio4r (~> 2.0)
12
+ websocket-driver (>= 0.6.1)
13
+ actionmailbox (6.0.3.4)
14
+ actionpack (= 6.0.3.4)
15
+ activejob (= 6.0.3.4)
16
+ activerecord (= 6.0.3.4)
17
+ activestorage (= 6.0.3.4)
18
+ activesupport (= 6.0.3.4)
19
+ mail (>= 2.7.1)
20
+ actionmailer (6.0.3.4)
21
+ actionpack (= 6.0.3.4)
22
+ actionview (= 6.0.3.4)
23
+ activejob (= 6.0.3.4)
24
+ mail (~> 2.5, >= 2.5.4)
25
+ rails-dom-testing (~> 2.0)
26
+ actionpack (6.0.3.4)
27
+ actionview (= 6.0.3.4)
28
+ activesupport (= 6.0.3.4)
29
+ rack (~> 2.0, >= 2.0.8)
30
+ rack-test (>= 0.6.3)
31
+ rails-dom-testing (~> 2.0)
32
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
33
+ actiontext (6.0.3.4)
34
+ actionpack (= 6.0.3.4)
35
+ activerecord (= 6.0.3.4)
36
+ activestorage (= 6.0.3.4)
37
+ activesupport (= 6.0.3.4)
38
+ nokogiri (>= 1.8.5)
39
+ actionview (6.0.3.4)
40
+ activesupport (= 6.0.3.4)
41
+ builder (~> 3.1)
42
+ erubi (~> 1.4)
43
+ rails-dom-testing (~> 2.0)
44
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
45
+ activejob (6.0.3.4)
46
+ activesupport (= 6.0.3.4)
47
+ globalid (>= 0.3.6)
48
+ activemodel (6.0.3.4)
49
+ activesupport (= 6.0.3.4)
50
+ activerecord (6.0.3.4)
51
+ activemodel (= 6.0.3.4)
52
+ activesupport (= 6.0.3.4)
53
+ activestorage (6.0.3.4)
54
+ actionpack (= 6.0.3.4)
55
+ activejob (= 6.0.3.4)
56
+ activerecord (= 6.0.3.4)
57
+ marcel (~> 0.3.1)
58
+ activesupport (6.0.3.4)
59
+ concurrent-ruby (~> 1.0, >= 1.0.2)
60
+ i18n (>= 0.7, < 2)
61
+ minitest (~> 5.1)
62
+ tzinfo (~> 1.1)
63
+ zeitwerk (~> 2.2, >= 2.2.2)
64
+ addressable (2.7.0)
65
+ public_suffix (>= 2.0.2, < 5.0)
66
+ bindex (0.8.1)
67
+ builder (3.2.4)
68
+ capybara (3.33.0)
69
+ addressable
70
+ mini_mime (>= 0.1.3)
71
+ nokogiri (~> 1.8)
72
+ rack (>= 1.6.0)
73
+ rack-test (>= 0.6.3)
74
+ regexp_parser (~> 1.5)
75
+ xpath (~> 3.2)
76
+ childprocess (3.0.0)
77
+ coderay (1.1.3)
78
+ concurrent-ruby (1.1.8)
79
+ crass (1.0.6)
80
+ database_cleaner (1.8.5)
81
+ database_cleaner-active_record (1.8.0)
82
+ activerecord
83
+ database_cleaner (~> 1.8.0)
9
84
  diff-lcs (1.4.4)
10
- rake (13.0.1)
11
- rspec (3.9.0)
12
- rspec-core (~> 3.9.0)
13
- rspec-expectations (~> 3.9.0)
14
- rspec-mocks (~> 3.9.0)
15
- rspec-core (3.9.2)
16
- rspec-support (~> 3.9.3)
17
- rspec-expectations (3.9.2)
85
+ docile (1.3.2)
86
+ erubi (1.10.0)
87
+ generator_spec (0.9.4)
88
+ activesupport (>= 3.0.0)
89
+ railties (>= 3.0.0)
90
+ globalid (0.4.2)
91
+ activesupport (>= 4.2.0)
92
+ i18n (1.8.8)
93
+ concurrent-ruby (~> 1.0)
94
+ loofah (2.9.0)
95
+ crass (~> 1.0.2)
96
+ nokogiri (>= 1.5.9)
97
+ mail (2.7.1)
98
+ mini_mime (>= 0.1.1)
99
+ marcel (0.3.3)
100
+ mimemagic (~> 0.3.2)
101
+ method_source (1.0.0)
102
+ mimemagic (0.3.5)
103
+ mini_mime (1.0.2)
104
+ mini_portile2 (2.5.0)
105
+ minitest (5.14.3)
106
+ nio4r (2.5.4)
107
+ nokogiri (1.11.1)
108
+ mini_portile2 (~> 2.5.0)
109
+ racc (~> 1.4)
110
+ pry (0.13.1)
111
+ coderay (~> 1.1)
112
+ method_source (~> 1.0)
113
+ pry-rails (0.3.9)
114
+ pry (>= 0.10.4)
115
+ public_suffix (4.0.6)
116
+ puma (5.0.4)
117
+ nio4r (~> 2.0)
118
+ racc (1.5.2)
119
+ rack (2.2.3)
120
+ rack-test (1.1.0)
121
+ rack (>= 1.0, < 3)
122
+ rails (6.0.3.4)
123
+ actioncable (= 6.0.3.4)
124
+ actionmailbox (= 6.0.3.4)
125
+ actionmailer (= 6.0.3.4)
126
+ actionpack (= 6.0.3.4)
127
+ actiontext (= 6.0.3.4)
128
+ actionview (= 6.0.3.4)
129
+ activejob (= 6.0.3.4)
130
+ activemodel (= 6.0.3.4)
131
+ activerecord (= 6.0.3.4)
132
+ activestorage (= 6.0.3.4)
133
+ activesupport (= 6.0.3.4)
134
+ bundler (>= 1.3.0)
135
+ railties (= 6.0.3.4)
136
+ sprockets-rails (>= 2.0.0)
137
+ rails-controller-testing (1.0.5)
138
+ actionpack (>= 5.0.1.rc1)
139
+ actionview (>= 5.0.1.rc1)
140
+ activesupport (>= 5.0.1.rc1)
141
+ rails-dom-testing (2.0.3)
142
+ activesupport (>= 4.2.0)
143
+ nokogiri (>= 1.6)
144
+ rails-html-sanitizer (1.3.0)
145
+ loofah (~> 2.3)
146
+ railties (6.0.3.4)
147
+ actionpack (= 6.0.3.4)
148
+ activesupport (= 6.0.3.4)
149
+ method_source
150
+ rake (>= 0.8.7)
151
+ thor (>= 0.20.3, < 2.0)
152
+ rake (13.0.3)
153
+ regexp_parser (1.8.2)
154
+ rspec-core (3.10.1)
155
+ rspec-support (~> 3.10.0)
156
+ rspec-expectations (3.10.1)
18
157
  diff-lcs (>= 1.2.0, < 2.0)
19
- rspec-support (~> 3.9.0)
20
- rspec-mocks (3.9.1)
158
+ rspec-support (~> 3.10.0)
159
+ rspec-mocks (3.10.2)
21
160
  diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.9.0)
23
- rspec-support (3.9.3)
161
+ rspec-support (~> 3.10.0)
162
+ rspec-rails (4.0.2)
163
+ actionpack (>= 4.2)
164
+ activesupport (>= 4.2)
165
+ railties (>= 4.2)
166
+ rspec-core (~> 3.10)
167
+ rspec-expectations (~> 3.10)
168
+ rspec-mocks (~> 3.10)
169
+ rspec-support (~> 3.10)
170
+ rspec-support (3.10.2)
171
+ rubyzip (2.3.0)
172
+ selenium-webdriver (3.142.7)
173
+ childprocess (>= 0.5, < 4.0)
174
+ rubyzip (>= 1.2.2)
175
+ simplecov (0.19.1)
176
+ docile (~> 1.1)
177
+ simplecov-html (~> 0.11)
178
+ simplecov-html (0.12.3)
179
+ simplecov-lcov (0.8.0)
180
+ sprockets (4.0.2)
181
+ concurrent-ruby (~> 1.0)
182
+ rack (> 1, < 3)
183
+ sprockets-rails (3.2.2)
184
+ actionpack (>= 4.0)
185
+ activesupport (>= 4.0)
186
+ sprockets (>= 3.0.0)
187
+ sqlite3 (1.4.2)
188
+ thor (1.1.0)
189
+ thread_safe (0.3.6)
190
+ tzinfo (1.2.9)
191
+ thread_safe (~> 0.1)
192
+ web-console (4.1.0)
193
+ actionview (>= 6.0.0)
194
+ activemodel (>= 6.0.0)
195
+ bindex (>= 0.4.0)
196
+ railties (>= 6.0.0)
197
+ webdrivers (4.4.1)
198
+ nokogiri (~> 1.6)
199
+ rubyzip (>= 1.3.0)
200
+ selenium-webdriver (>= 3.0, < 4.0)
201
+ websocket-driver (0.7.3)
202
+ websocket-extensions (>= 0.1.0)
203
+ websocket-extensions (0.1.5)
204
+ xpath (3.2.0)
205
+ nokogiri (~> 1.8)
206
+ zeitwerk (2.4.2)
24
207
 
25
208
  PLATFORMS
26
209
  ruby
@@ -28,8 +211,20 @@ PLATFORMS
28
211
  DEPENDENCIES
29
212
  abyme!
30
213
  bundler (~> 2.0)
214
+ capybara
215
+ database_cleaner-active_record
216
+ generator_spec
217
+ pry-rails
218
+ puma
219
+ rails
220
+ rails-controller-testing
31
221
  rake (~> 13.0)
32
- rspec (~> 3.0)
222
+ rspec-rails
223
+ simplecov
224
+ simplecov-lcov
225
+ sqlite3
226
+ web-console
227
+ webdrivers
33
228
 
34
229
  BUNDLED WITH
35
- 2.0.2
230
+ 2.1.4
data/README.md CHANGED
@@ -1,16 +1,46 @@
1
- # Abyme 🕳
1
+ # abyme 🕳
2
2
 
3
- abyme is a modern take on handling dynamic nested forms in Rails 6+ using StimulusJS.
3
+ [![Gem Version](https://badge.fury.io/rb/abyme.svg)](https://badge.fury.io/rb/abyme)
4
+ ![build](https://github.com/bear-in-mind/abyme/workflows/build/badge.svg)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/f591a9e00f7cf5188ad5/maintainability)](https://codeclimate.com/github/bear-in-mind/abyme/maintainability)
6
+ [![Coverage Status](https://coveralls.io/repos/github/bear-in-mind/abyme/badge.svg)](https://coveralls.io/github/bear-in-mind/abyme?branch=master)
4
7
 
5
- ## Disclaimer
6
- This project is still a work in progress and subject to change. We encourage not to use it in production code just yet.
8
+ abyme is an easy and framework-agnostic way to handle nested attributes in Rails, using [stimulus](https://stimulusjs.org/handbook/introduction) under the hood. Here's an example :
9
+ ```ruby
10
+ # views/projects/_form.html.erb
11
+ <%= form_for @project do |f| %>
12
+ <%= f.text_field :title %>
13
+ <%= f.text_area :description %>
14
+ <%= f.submit 'Save' %>
15
+
16
+ <%= f.abyme_for(:tasks) %>
17
+ <% end %>
18
+ ```
19
+ Supposing you have a `Project` that `has_many :tasks` and a partial located in `views/abyme/_task_fields` containing your form fields for `tasks`, the `abyme_for` command will generate and display 3 elements in this order :
20
+ - A `div` containing all task fields for `@project.tasks` (either persisted or already built instances of `tasks`)
21
+ - A `div` which will contain all additional tasks about to be created (added through the `Add task` button below)
22
+ - A `button` to generate fields for new instances of tasks
7
23
 
8
- Any enhancement proposition or bug report welcome !
24
+ Have a look below to learn more about configuration and all its different options.
9
25
 
10
- General remarks :
11
- * A demo app will soon be online.
12
- * For now, the gem is tested through our demo app. Specific autonomous tests will be transfered/written in the following days.
13
- * Help is very much wanted on the Events part of the gem (see bottom of this documentation)
26
+ ## Demo app
27
+
28
+ ![Demo preview](https://res.cloudinary.com/aux-belles-autos/image/upload/v1603040053/abyme-preview.gif)
29
+
30
+ Check out our demo app here : https://abyme-demo.herokuapp.com/
31
+
32
+ Source code is right here : https://github.com/bear-in-mind/abyme_demo
33
+
34
+ ## Breaking changes
35
+ Careful ! As of February 12th, we changed quite a few methods name :
36
+ In model:
37
+ - `abyme_for` became `abymize`
38
+ In views:
39
+ - `abymize(:association, f)` became `f.abyme_for(:association)`
40
+ - `add_association` became `add_associated_record`
41
+ - `remove_association` became `remove_associated_record`
42
+
43
+ If you update, don't forget to change those ! All changes are reflected in the README below.
14
44
 
15
45
  ## Installation
16
46
 
@@ -23,7 +53,7 @@ gem 'abyme'
23
53
  And then execute:
24
54
 
25
55
  $ bundle
26
- $ yarn add 'abyme'
56
+ $ yarn add abyme
27
57
 
28
58
 
29
59
  Assuming you [already installed Stimulus](https://stimulusjs.org/handbook/introduction), add this in `app/javascript/controllers/index.js` :
@@ -41,272 +71,180 @@ application.load(definitionsFromContext(context))
41
71
  application.register('abyme', AbymeController)
42
72
  ```
43
73
 
44
- ## What are nested forms and why a new gem ?
74
+ ## Get started
75
+
76
+ To learn more about the *why* of this gem, check out our [wiki](https://github.com/bear-in-mind/abyme/wiki/What-are-nested-forms-and-why-a-new-gem-%3F)
45
77
 
46
- Nested forms (or more accurately *nested fields* or *nested attributes*) are forms that deal with associated models. Let's picture a `Project` model that `has_many :tasks`. A nested form will allow you to create a project along with one or several tasks **within a single form**. If `Tasks` were to have associations on their own, like `:comments`, you could also, still in the same form, instantiate comments along with their parent models.
78
+ You may also check out our [step by step tutorial](https://github.com/bear-in-mind/abyme/wiki/Step-by-step-Tutorial)
47
79
 
48
- Rails provides [its own helper](https://api.rubyonrails.org/v6.0.1/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for) to handle nested attributes. **abyme** is basically a smart wrapper around it, offering easier syntax along with some fancy additions. To work properly, some configuration will be required in both models and controllers (see below).
49
80
 
50
- What Rails doesn't provide natively is the possibility to **dynamically add new associations on the fly**, which requires Javascript implementation. What this means it that you would normally have to know in advance how many fields you'd like to display (1, 2 or any number of `:tasks`), which isn't very usable in this day and age. This is what the [cocoon gem](https://github.com/nathanvda/cocoon) has been helping with for the past 7 years. This gem still being implemented in JQuery (which [Rails dropped as a dependency](https://github.com/rails/rails/issues/25208)), we wanted to propose a more plug'n'play approach, using Basecamp's [Stimulus](https://stimulusjs.org/) instead.
81
+ ### Model
51
82
 
52
- ## Basic Configuration
83
+ 💡 Don't forget to `include Abyme::Model` in your parent model
53
84
 
54
- ### Models
55
- Let's consider a to-do application with Projects having many Taks, themselves having many Comments.
85
+ #### #abymize(:association, permit: nil, reject: nil, options = {})
86
+ In models, the `abyme_for :association` acts as an alias for this command :
56
87
  ```ruby
57
- # models/project.rb
58
- class Project < ApplicationRecord
59
- has_many :tasks
60
- validates :title, :description, presence: true
61
- end
62
-
63
- # models/task.rb
64
- class Task < ApplicationRecord
65
- belongs_to :project
66
- has_many :comments
67
- validates :title, :description, presence: true
68
- end
69
-
70
- # models/comment.rb
71
- class Comment < ApplicationRecord
72
- belongs_to :task
73
- validates :content, presence: true
74
- end
88
+ accepts_nested_attributes_for :association, reject_if: :all_blank, :allow_destroy: true
75
89
  ```
76
- The end-goal here is to be able to create a project along with different tasks, and immediately add comments to some of these tasks ; all within a single form.
77
- What we'll have is a 2-level nested form. Thus, we'll need to configure our `Project` and `Task` models like so :
90
+
91
+ * `permit: []` : allows you to generate a hash of attributes that can be easily called on the controller side through the `::abyme_attributes` class method (see details below).
78
92
  ```ruby
79
- # models/project.rb
80
- class Project < ApplicationRecord
81
- include Abyme::Model
82
- has_many :tasks, inverse_of: :project
83
- # ...
84
- abyme_for :tasks
85
- end
86
-
87
- # models/task.rb
88
- class Task < ApplicationRecord
89
- include Abyme::Model
90
- has_many :comments, inverse_of: :task
91
- # ...
92
- abyme_for :comments
93
- end
93
+ abymize :association, permit: [:name, :description]
94
+
95
+ # You may also permit all attributes like so :
96
+ abymize :association, permit: :all_attributes
94
97
  ```
95
- Note the use of the `inverse_of` option. It is needed for Rails to effectively associate children to their yet unsaved parent. Have a peek to the bottom of [this page](https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for) for more info.
96
-
97
- ### Controller
98
- Since we're dealing with one form, we're only concerned with one controller : the one the form routes to. In our example, this would be the `ProjectsController`.
99
- The only configuration needed here will concern our strong params. Nested attributes require a very specific syntax to white-list the permitted attributes. It looks like this :
100
98
 
99
+ * `reject: []` : allows you to add all attributes to `::abyme_attributes`, excepted the ones specified.
101
100
  ```ruby
102
- def project_params
103
- params.require(:project).permit(
104
- :title, :description, tasks_attributes: [
105
- :id, :title, :description, :_destroy, comments_attributes: [
106
- :id, :content, :_destroy
107
- ]
108
- ]
109
- )
110
- end
101
+ abymize :association, reject: [:password]
111
102
  ```
112
- A few explanations here.
113
103
 
114
- * To permit a nested model attributes in your params, you'll need to pass the `association_attributes: [...]` hash at the end of your resource attributes. Key will always be `association_name` followed by `_attributes`, while the value will be an array of symbolized attributes, just like usual.
104
+ * `options: {}` : [the same options] you may pass to the `accepts_nested_attributes` method (see [this link](https://api.rubyonrails.org/v6.1.0/classes/ActiveRecord/NestedAttributes/ClassMethods.html) for details)
105
+ ```ruby
106
+ abyme_for :association, limit: 3, allow_destroy: false
107
+ ```
115
108
 
116
- > **Note**: if your association is a singular one (`has_one` or `belongs_to`) the association will be singular ; if a Project `has_one :owner`, you would then need to pass `owner_attributes: [...]`)
109
+ #### ::abyme_attributes
110
+ Returns a hash to the right format to be included in the `strong params` on the controller side. For a `Project` model with nested `:tasks` :
111
+ ```ruby
112
+ Project.abyme_attributes
113
+ # => {tasks_attributes: [:title, :description, :id, :_destroy]}
114
+ ```
117
115
 
118
- * You may have remarked the presence of `id` and `_destroy` among those params. These are necessary for edit actions : if you want to allow your users to destroy or update existing records, these are **mandatory**. Otherwise, Rails won't be able to recognize these records as existing ones, and will just create new ones. More info [here](https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html).
116
+ ### Controller
117
+ #### #abyme_attributes
118
+ Infers the name of the resource from the controller name, and calls the `::abyme_attributes` method on it. Hence, in your `ProjectsController` :
119
+ ```ruby
120
+ def project_params
121
+ params.require(:project).permit(:title, :description, abyme_attributes)
122
+ end
123
+ ```
119
124
 
120
- ## Basic Usage
125
+ ### Views
121
126
 
122
- Dealing with nested attributes means you'll generally have to handle a few things inside your form:
123
- * Display fields for the **persisted records** (here, already existing `:tasks`)
124
- * Display fields for the **new records** (future `:tasks` not yet persisted)
125
- * A button to **trigger the addition** of fields for a new resource (an `Add a new task` button)
126
- * A button to **remove fields** for a given resource (`Remove task`)
127
+ #### #abyme_for(:association, options = {}, &block)
128
+ This is the container for all your nested fields. It takes the symbolized association as a parameter, along with options, and an optional block to specify any layout you may wish for the different parts of the `abyme` builder.
127
129
 
128
- abyme provides helper methods for all these. Here's how our form for `Project` looks like when using default values:
130
+ 💡 Please note an id is automatically added to this element, which value is : `abyme--association_name`.
129
131
 
132
+ 💡 If you don't pass a block, `records`, `new_records` and `add_association` will be called and will appear in this order in your layout.
133
+ * `partial: ` : allows you to indicate a custom partial path for both `records` and `new_records`
130
134
  ```ruby
131
- # views/projects/_form.html.erb
132
- <%= simple_form_for @project do |f| %>
133
- <%= f.input :title %>
134
- <%= f.input :description %>
135
- <%= f.submit 'Save' %>
136
-
137
- <%= abymize(:tasks, f) do |abyme| %>
135
+ <%= f.abyme_for(:tasks, partial: 'projects/task_fields') do |abyme| %>
138
136
  <%= abyme.records %>
139
137
  <%= abyme.new_records %>
140
138
  <%= add_association %>
141
139
  <% end %>
142
- <% end %>
143
- ```
144
-
145
- `abyme.records` will contain the persisted associations fields, while `abyme.new_records` will contain fields for the new associations. `add_association` will by default generate a button with a text of type "Add `resource_name`". To work properly, this method **has** to be called **inside the block** passed to the `abymize` method.
146
-
147
- Now where's the code for these fields ? abyme will assume a **partial** to be present in the directory `/views/abyme` with a *name respecting this naming convention* (just like with [cocoon](https://github.com/nathanvda/cocoon#basic-usage)): `_singular_association_name_fields.html.erb`.
148
-
149
- This partial might look like this:
150
- ```ruby
151
- # views/abyme/_task_fields.html.erb
152
- <%= f.input :title %>
153
- <%= f.input :description %>
154
- <%= f.hidden_field :_destroy %>
155
-
156
- <%= remove_association(tag: :div) do %>
157
- <i class="fas fa-trash"></i>
158
- <% end %>
159
140
  ```
160
-
161
- Note the presence of the `remove_association` button. Here, we pass it an option to make it a `<div>`, as well as a block to customize its content. Don't forget the `_destroy` attribute, needed to mark items for destruction.
162
-
163
- ### What about the controller ?
164
-
165
- What about it ? Well, not much. That's the actual magical thing about `nested_attributes`: once your model is aware of its acceptance of those for a given association, and your strong params are correctly configured, there's nothing else to do.
166
- `@project.create(project_params)` is all you'll need to save a project along with its descendants 👨‍👧‍👧
167
-
168
- ### Auto mode
169
-
170
- Let's now take care of our comments fields. We'll add these using our neat *automatic mode*: just stick this line at the end of the partial:
141
+ * `limit: ` : allows you to limit the number of new fields that can be created through JS. If you need to limit the number of associations in database, you will need to add validations. You can also pass an option [in your model as well](https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for).
171
142
  ```ruby
172
- # views/abyme/_task_fields.html.erb
173
- # ... rest of the partial above
174
- <%= abymize(:comments, f) %>
143
+ <%= f.abyme_for(:tasks, limit: 5) do |abyme| %>
144
+ # Beyond 5 tasks, the add button won't add any more fields. See events section below to see how to handle the 'abyme:limit-reached' event
145
+ <%= abyme.records %>
146
+ <%= abyme.new_records %>
147
+ <%= add_association %>
148
+ <% end %>
175
149
  ```
176
- Where's the rest of the code ? Well, if the default configuration you saw above in the `_form.html.erb` suits you, and the order in which the different resources appear feels right (persisted first, new fields second, and the 'Add' button last), then you can just spare the block, and it will be taken care of for you. We'll just write our `_comment_fields.html.erb` partial in the `views/abyme` directory and we'll be all set.
177
-
178
- ## Advanced usage
179
- ### Models
180
- In models, the `abyme_for :association` acts as an alias for this command :
181
-
150
+ * `min_count: ` by default, there won't be any blank fields added on page load. By passing a `min_count` option, you can set how many empty fields should appear in the form.
182
151
  ```ruby
183
- accepts_nested_attributes_for :association, reject_if: :all_blank, :allow_destroy: true
152
+ <%= f.abyme_for(:tasks, min_count: 1) do |abyme| %>
153
+ # 1 blank task will automatically be added to the form.
154
+ <%= abyme.records %>
155
+ <%= abyme.new_records %>
156
+ <%= add_association %>
157
+ <% end %>
184
158
  ```
185
159
 
186
- Which is the way you would configure `nested_attributes` 90% of the time. Should you want to pass [any available options](https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for) to this method or change those, you may just pass them as with the original method :
187
- ```ruby
188
- abyme_for :association, limit: 3, allow_destroy: false
189
- ```
160
+ *If you're not passing a block*, the `abyme_for` method can take a few additional options:
161
+ * `button_text: ` this will set the `add_association` button text to the string of your choice.
190
162
 
191
- ### Views
163
+ 💡 All options that should be passed to either `records` or `new_records` below can be passed here and will be passed down.
192
164
 
193
165
  #### #records
194
166
  A few options can be passed to `abyme.records`:
195
167
  * `collection:` : allows you to pass a collection of your choice to only display specific objects.
196
168
  ```ruby
197
- <%= abymize(:tasks, f) do |abyme| %>
169
+ <%= f.abyme_for(:tasks) do |abyme| %>
198
170
  <%= abyme.records(collection: @project.tasks.where(done: false)) %>
199
171
  <%= abyme.new_records %>
200
- <%= add_association %>
172
+ <%= add_associated_record %>
201
173
  <% end %>
202
174
  ```
203
175
  * `order:` : allows you to pass an ActiveRecord `order` method to sort your instances the way you want.
204
176
  ```ruby
205
- <%= abymize(:tasks, f) do |abyme| %>
177
+ <%= f.abyme_for(:tasks) do |abyme| %>
206
178
  <%= abyme.records(order: { created_at: :asc }) %>
207
179
  <%= abyme.new_records %>
208
- <%= add_association %>
180
+ <%= add_associated_record %>
209
181
  <% end %>
210
182
  ```
211
- * `partial:` : allows you to indicate a custom partial, if one has not already been passed to `abymize`.
183
+ * `partial:` : allows you to indicate a custom partial, if one has not already been passed to `abyme_for`.
212
184
  ```ruby
213
- <%= abymize(:tasks, f) do |abyme| %>
185
+ <%= f.abyme_for(:tasks) do |abyme| %>
214
186
  <%= abyme.records %>
215
187
  <%= abyme.new_records(partial: 'projects/task_fields') %>
216
- <%= add_association %>
188
+ <%= add_associated_record %>
217
189
  <% end %>
218
190
  ```
219
191
  * `fields_html:` : gives you the possibility to add any HTML attribute you may want to each set of fields. By default, an `abyme--fields` and an `singular_association-fields` class are already present.
220
192
  ```ruby
221
- <%= abymize(:tasks, f) do |abyme| %>
193
+ <%= f.abyme_for(:tasks) do |abyme| %>
222
194
  <%= abyme.records(fields_html: { class: "some-class" }) %>
223
195
  # Every set of persisted fields will have these 3 classes : 'abyme--fields', 'task-fields', and 'some-class'
224
196
  <%= abyme.new_records %>
225
- <%= add_association %>
197
+ <%= add_associated_record %>
226
198
  <% end %>
227
199
  ```
228
- * `wrapper_html:` : gives you the possibility to add any HTML attribute you may want to the wrapper containing all fields.
200
+ * `wrapper_html:` : gives you the possibility to add any HTML attribute you may want to the wrapper containing all persisted fields.
229
201
  ```ruby
230
- <%= abymize(:tasks, f) do |abyme| %>
202
+ <%= f.abyme_for(:tasks) do |abyme| %>
231
203
  <%= abyme.records(wrapper_html: { class: "persisted-records" }) %>
232
204
  # The wrapper containing all persisted task fields will have an id "abyme-tasks-wrapper" and a class "persisted-records"
233
205
  <%= abyme.new_records %>
234
- <%= add_association %>
206
+ <%= add_associated_record %>
235
207
  <% end %>
236
208
  ```
237
209
  #### #new_records
238
210
  Here are the options that can be passed to `abyme.new_records`:
239
211
  * `position:` : allows you to specify whether new fields added dynamically should go at the top or at the bottom. `:end` is the default value.
240
212
  ```ruby
241
- <%= abymize(:tasks, f) do |abyme| %>
213
+ <%= f.abyme_for(:tasks) do |abyme| %>
242
214
  <%= abyme.records %>
243
215
  <%= abyme.new_records(position: :start) %>
244
- <%= add_association %>
216
+ <%= add_associated_record %>
245
217
  <% end %>
246
218
  ```
247
219
  * `partial:` : same as `#records`
248
220
  * `fields_html:` : same as `#records`
249
221
  * `wrapper_html:` : same as `#records`
250
222
 
251
- #### #add_association, #remove_association
223
+ #### #add_associated_record, #remove_associated_record
252
224
  These 2 methods behave the same. Here are their options :
253
225
  * `tag:` : allows you to specify a tag of your choosing, like `:a`, or `:div`. Default is `:button`.
254
226
  * `content:` : the text to display inside the element. Default is `Add association_name`
255
227
  * `html:` : gives you the possibility to add any HTML attribute you may want to the element.
256
228
  ```ruby
257
- <%= abymize(:tasks, f) do |abyme| %>
229
+ <%= f.abyme_for(:tasks) do |abyme| %>
258
230
  # ...
259
- <%= add_association(tag: :a, content: "Add a super task", html: {id: "add-super-task"}) %>
231
+ <%= add_associated_record(tag: :a, content: "Add a super task", html: {id: "add-super-task"}) %>
260
232
  <% end %>
261
233
  ```
262
234
 
263
235
  As you may have seen above, you can also pass a block to the method to give it whatever HTML content you want :
264
236
  ```ruby
265
- <%= abymize(:tasks, f) do |abyme| %>
237
+ <%= f.abyme_for(:tasks) do |abyme| %>
266
238
  # ...
267
- <%= add_association(tag: :div, html: {id: "add-super-task", class: "flex"}) do %>
239
+ <%= add_associated_record(tag: :div, html: {id: "add-super-task", class: "flex"}) do %>
268
240
  <i class="fas fa-plus"></i>
269
241
  <h2>Add a super task</h2>
270
242
  <% end %>
271
243
  <% end %>
272
244
  ```
273
245
 
274
-
275
- #### #abymize(:association, form_object)
276
- This is the container for all your nested fields. It takes two parameters (the symbolized association and the `form_builder`), and some optional ones. Please note an id is automatically added to this element, which value is : `abyme--association`.
277
- * `partial:` : allows you to indicate a custom partial path for both `records` and `new_records`
278
- ```ruby
279
- <%= abymize(:tasks, f, partial: 'projects/task_fields') do |abyme| %>
280
- <%= abyme.records %>
281
- <%= abyme.new_records %>
282
- <%= add_association %>
283
- <% end %>
284
- ```
285
- * `limit:` : allows you to limit the number of new fields that can be created through JS. If you need to limit the number of associations in database, you will need to add validations. You can also pass an option [in your model as well](https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for).
286
- ```ruby
287
- <%= abymize(:tasks, f, limit: 5) do |abyme| %>
288
- # Beyond 5 tasks, the add button won't add any more fields. See events section below to see how to handle the 'abyme:limit-reached' event
289
- <%= abyme.records %>
290
- <%= abyme.new_records %>
291
- <%= add_association %>
292
- <% end %>
293
- ```
294
- * `min_count` : by default, there won't be any blank fields added on page load. By passing a `min_count` option, you can set how many empty fields should appear in the form.
295
- ```ruby
296
- <%= abymize(:tasks, f, min_count: 1) do |abyme| %>
297
- # 1 blank task will automatically be added to the form.
298
- <%= abyme.records %>
299
- <%= abyme.new_records %>
300
- <%= add_association %>
301
- <% end %>
302
- ```
303
-
304
- *When in auto mode*, the abymize method can take a few options:
305
- * `button_text:` : this will set the `add_association` button text to the string of your choice.
306
- * All options that should be passed to either `records` or `new_records` can be passed here and will be passed down.
307
-
308
246
  ## Events
309
- This part is still a work in progress and subject to change. We're providing some basic self-explanatory events to attach to. These are emitted by the main container (created by the `abymize` method).
247
+ This part is still a work in progress and subject to change. We're providing some basic self-explanatory events to attach to. These are emitted by the main container (created by the `abyme_for` method).
310
248
 
311
249
  We're currently thinking about a way to attach to these via Stimulus. Coming soon !
312
250