質問編集履歴

3

修正

2022/09/04 23:11

投稿

happy
happy

スコア13

test CHANGED
File without changes
test CHANGED
@@ -1,279 +1,5 @@
1
1
  ### 前提
2
2
 
3
3
  rails と javascriptを用いて家計簿アプリを実装しています。
4
- ユーザー管理機能はdeviseを使用し、wizard形式になっています。
5
-
6
- - 1ページ目:ユーザー情報ページ
7
- - 2ページ目:資産登録ページ
8
- - 3ページ目:負債登録ページ
9
-
10
- ### 実現したいこと
11
-
12
- 2、3ページ目について、非同期にてフォームの追加と削除ができるようになっています。
13
-
14
- 現状、1つ目のフォームしかデータベースに保存されません。
15
- 入力した値すべてをデータベースに保存したいです。
16
-
17
- [![Image from Gyazo](https://i.gyazo.com/9963651ee0018819b9d6f0ca8400f959.gif)](https://gyazo.com/9963651ee0018819b9d6f0ca8400f959)
18
-
19
- ### コントローラ
20
-
21
- - app/controllers/users/registrations_controlntroller.rb
22
-
23
- ```ruby
24
- # frozen_string_literal: true
25
-
26
- class Users::RegistrationsController < Devise::RegistrationsController
27
- # before_action :configure_sign_up_params, only: [:create]
28
- # before_action :configure_account_update_params, only: [:update]
29
-
30
- def new
31
- @user = User.new
32
- end
33
-
34
- #1ページ目の情報をsessionに保持
35
- def create
36
- @user = User.new(sign_up_params)
37
- render :new and return unless @user.valid?
38
-
39
- session['devise.regist_data'] = { user: @user.attributes }
40
- session['devise.regist_data'][:user]['password'] = params[:user][:password]
41
- @assettable = @user.build_assettable
42
- render :new_assettable
43
- end
44
-
45
- #1, 2ページ目の情報をsessionに保持
46
- def create_assettable
47
- @user = User.new(session['devise.regist_data']['user'])
48
- @assettable = Assettable.new(assettable_params)
49
- render :new_assettable and return unless @assettable.valid?
50
-
51
- session['devise.regist_data']['assettable'] = { assettable: @assettable.attributes }
52
- @debttable = @user.build_debttable
53
- render :new_debttable
54
- end
55
-
56
- #1〜3ページの情報を保存
57
- def create_debttable
58
- @user = User.new(session['devise.regist_data']['user'])
59
- @assettable = Assettable.new(session['devise.regist_data']['assettable']['assettable'])
60
- @user.build_assettable(@assettable.attributes)
61
- @user.save
62
- @debttable = Debttable.new(debttable_params)
63
- render :new_debttable and return unless @debttable.valid?
64
-
65
- @user.build_debttable(@debttable.attributes)
66
- @user.save
67
-
68
- session['devise.regist_data'].clear
69
- sign_in(:user, @user)
70
- end
71
-
72
- private
73
-
74
- def assettable_params
75
- params.require(:assettable).permit(:balance, :list_id)
76
- end
77
-
78
- def debttable_params
79
- params.require(:debttable).permit(:balance, :list_id)
80
- end
81
-
82
- # GET /resource/sign_up
83
- # def new
84
- # super
85
- # end
86
-
87
- # POST /resource
88
- # def create
89
- # super
90
- # end
91
-
92
- # GET /resource/edit
93
- # def edit
94
- # super
95
- # end
96
-
97
- # PUT /resource
98
- # def update
99
- # super
100
- # end
101
-
102
- # DELETE /resource
103
- # def destroy
104
- # super
105
- # end
106
-
107
- # GET /resource/cancel
108
- # Forces the session data which is usually expired after sign
109
- # in to be expired now. This is useful if the user wants to
110
- # cancel oauth signing in/up in the middle of the process,
111
- # removing all OAuth session data.
112
- # def cancel
113
- # super
114
- # end
115
-
116
- # protected
117
-
118
- # If you have extra params to permit, append them to the sanitizer.
119
- # def configure_sign_up_params
120
- # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
121
- # end
122
-
123
- # If you have extra params to permit, append them to the sanitizer.
124
- # def configure_account_update_params
125
- # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
126
- # end
127
-
128
- # The path used after sign up.
129
- # def after_sign_up_path_for(resource)
130
- # super(resource)
131
- # end
132
-
133
- # The path used after sign up for inactive accounts.
134
- # def after_inactive_sign_up_path_for(resource)
135
- # super(resource)
136
- # end
137
- end
138
- ```
139
-
140
- ### ターミナル
141
- create_assettableメソッドを `binding.pry` でデバックした結果です。
142
- 現状params の中身に1つ目のフォームの情報しか入っていません。
143
- `"assettable"=>{"list_id"=>"1", "balance"=>"5000"}, `
144
-
145
- ```console
146
- 23: def create_assettable
147
- => 24: binding.pry
148
- 25: @user = User.new(session['devise.regist_data']['user'])
149
- 26: @assettable = Assettable.new(assettable_params)
150
- 27: render :new_assettable and return unless @assettable.valid?
151
- 28:
152
- 29: session['devise.regist_data']['assettable'] = { assettable: @assettable.attributes }
153
- 30: @debttable = @user.build_debttable
154
- 31: render :new_debttable
155
- 32: end
156
-
157
- [1] pry(#<Users::RegistrationsController>)> params
158
- => <ActionController::Parameters {"authenticity_token"=>"xxxxx", "assettable"=>{"list_id"=>"1", "balance"=>"5000"}, "commit"=>"次へ", "controller"=>"users/registrations", "action"=>"create_assettable"} permitted: false>
159
- ```
160
-
161
- ### テーブル設計
162
- [![Image from Gyazo](https://i.gyazo.com/3976b417d8ddd01fe3d4ac49c9c4e1f6.jpg)](https://gyazo.com/3976b417d8ddd01fe3d4ac49c9c4e1f6)
163
-
164
- ### ルーティング
165
-
166
- ```ruby
167
- Rails.application.routes.draw do
168
- root to: 'top#index'
169
- resources :books, only: :index
170
-
171
- devise_for :users, controllers: {
172
- registrations: 'users/registrations'
173
- }
174
- devise_scope :user do
175
- get 'assettables', to: 'users/registrations#new_assettable'
176
- post 'assettables', to: 'users/registrations#create_assettable'
177
- get 'debttables', to: 'users/registrations#new_debttable'
178
- post 'debttables', to: 'users/registrations#create_debttable'
179
- end
180
-
181
- end
182
- ```
183
-
184
- ### コード
185
-
186
- - 2ページ目のビュー(3ページ目も同様です)
187
-
188
- ```ruby
189
- <div class="wrapper">
190
- <%= render "devise/shared/header" %>
191
-
192
- <%= form_with model: @assettable, class: 'registration-main', local: true do |f| %>
193
- <%= render "devise/shared/error_messages", resource: @assettable %>
194
-
195
- <%# フォームエリア %>
196
- <div class="form-area1">
197
- <div class='form-header1'>
198
- <h1 class="form-title">資産</h1>
199
- <p class="form-content">現在の資産状況について教えてください。</p>
200
- </div>
201
-
202
- <%# フォームエリア %>
203
- <div class="form-input">
204
- <div class="form-field" id="form-field">
205
- <div class="selectbox" id="selectbox_0">
206
- <%= f.collection_select :list_id, List.where(code: 100..199), :id, :code_name, class: "form-select form-select-sm", include_blank: "選択してください" %>
207
- </div>
208
- <%= f.text_field :balance, placeholder:"例) 1000" ,id: "input-balance_0"%>
209
- <button id="0" onclick="deleteBtn(this)">削除</button>
210
- </div>
211
- <%#input type="button" value="削除" id="delete-btn"%>
212
- <input type="button" value="追加" id="add-btn">
213
- </div>
214
4
 
215
5
 
216
- <div class='form-bottom-text'>
217
- <%= f.submit "次へ" ,class: "btn btn-outline-secondary"%>
218
- </div>
219
-
220
- <% end %>
221
- </div>
222
- ```
223
-
224
- ```javascript
225
- const i = 1 ;
226
- const minCount = 0;
227
- const maxCount = 5;
228
-
229
- //追加ボタン
230
- function addForm() {
231
- const add = document.getElementById("add-btn");
232
- add.addEventListener("click", () => {
233
- //フォーム生成
234
- const select = document.getElementById("selectbox_0");
235
- const select_copy = select.cloneNode(true);
236
- select_copy.id = 'selectbox_' + i;
237
- const input = document.getElementById("input-balance_0");
238
- const input_copy = input.cloneNode(true);
239
- input_copy.id = 'input-balance_' + i;
240
- input_copy.value = ''
241
- if (i < maxCount) {
242
- const parent = document.getElementById('form-field');
243
- parent.appendChild(select_copy);
244
- parent.appendChild(input_copy);
245
- }
246
-
247
- //削除ボタン生成
248
- const button_data = document.createElement('button');
249
- button_data.id = i;
250
- button_data.onclick = function(){deleteBtn(this);}
251
- button_data.innerHTML = '削除';
252
- if (i < maxCount) {
253
- const parent = document.getElementById('form-field');
254
- var input_area = document.getElementById(select_copy.id);
255
- parent.appendChild(button_data);
256
- }
257
- i++ ;
258
- });
259
- };
260
- window.addEventListener('load', addForm);
261
-
262
-
263
- //削除ボタン
264
- window.deleteBtn = function(target){
265
- const target_id = target.id;
266
- const parent = document.getElementById('form-field');
267
- const slt_id = document.getElementById('selectbox_' + target_id);
268
- const ipt_id = document.getElementById('input-balance_' + target_id);
269
- const tgt_id = document.getElementById(target_id);
270
- if (target_id > minCount){
271
- parent.removeChild(slt_id);
272
- parent.removeChild(ipt_id);
273
- parent.removeChild(tgt_id);
274
- }
275
- }
276
- ```
277
-
278
- 何卒よろしくお願いいたします。
279
-

2

修正

2022/08/28 10:42

投稿

happy
happy

スコア13

test CHANGED
File without changes
test CHANGED
@@ -11,19 +11,10 @@
11
11
 
12
12
  2、3ページ目について、非同期にてフォームの追加と削除ができるようになっています。
13
13
 
14
- 以下がうまくいかず苦戦しています・・。
15
-
16
- - 1行目のフォーム入力後、 `追加` をクリックすると、入力した値が入った状態でフォームが追加される
17
-
18
- →追加した際、フォームに値が入ってない状態にしたい。
19
-
20
- - 目のフォームしかデータベースに保存されない
14
+ 現状、目のフォームしかデータベースに保存されません
21
-
22
- 入力した値すべて、入力されるようにしたい。
15
+ 入力した値すべてをデータベース保存したいです
23
-
24
- 以上2点です。
16
+
25
-
26
- [![Image from Gyazo](https://i.gyazo.com/65e617caef4f3538d8f5a91967f57354.gif)](https://gyazo.com/65e617caef4f3538d8f5a91967f57354)
17
+ [![Image from Gyazo](https://i.gyazo.com/9963651ee0018819b9d6f0ca8400f959.gif)](https://gyazo.com/9963651ee0018819b9d6f0ca8400f959)
27
18
 
28
19
  ### コントローラ
29
20
 
@@ -147,14 +138,24 @@
147
138
  ```
148
139
 
149
140
  ### ターミナル
150
- - create_assettableメソッドを `binding.pry` でデバックした結果です。
141
+ create_assettableメソッドを `binding.pry` でデバックした結果です。
151
- - 2ページ目の情報を保存する際の `params` です
142
+ 現状params の中身に1つ目のフォームの情報しか入っていません
152
-
143
+ `"assettable"=>{"list_id"=>"1", "balance"=>"5000"}, `
153
144
 
154
145
  ```console
155
- #assettablesテーブルに保存
146
+ 23: def create_assettable
147
+ => 24: binding.pry
148
+ 25: @user = User.new(session['devise.regist_data']['user'])
149
+ 26: @assettable = Assettable.new(assettable_params)
150
+ 27: render :new_assettable and return unless @assettable.valid?
151
+ 28:
152
+ 29: session['devise.regist_data']['assettable'] = { assettable: @assettable.attributes }
153
+ 30: @debttable = @user.build_debttable
154
+ 31: render :new_debttable
155
+ 32: end
156
+
156
157
  [1] pry(#<Users::RegistrationsController>)> params
157
- => <ActionController::Parameters {"assettable"=>{"list_id"=>"1", "balance"=>"333"}, "commit"=>"次へ", "controller"=>"users/registrations", "action"=>"create_assettable"} permitted: false>
158
+ => <ActionController::Parameters {"authenticity_token"=>"xxxxx", "assettable"=>{"list_id"=>"1", "balance"=>"5000"}, "commit"=>"次へ", "controller"=>"users/registrations", "action"=>"create_assettable"} permitted: false>
158
159
  ```
159
160
 
160
161
  ### テーブル設計
@@ -184,7 +185,7 @@
184
185
 
185
186
  - 2ページ目のビュー(3ページ目も同様です)
186
187
 
187
- ```r
188
+ ```ruby
188
189
  <div class="wrapper">
189
190
  <%= render "devise/shared/header" %>
190
191
 
@@ -200,35 +201,78 @@
200
201
 
201
202
  <%# フォームエリア %>
202
203
  <div class="form-input">
203
- <div class="form-field">
204
+ <div class="form-field" id="form-field">
205
+ <div class="selectbox" id="selectbox_0">
204
- <%= f.collection_select :list_id, List.where(code: 100..199), :id, :code_name, class: "form-select form-select-sm", include_blank: "選択してください" %>
206
+ <%= f.collection_select :list_id, List.where(code: 100..199), :id, :code_name, class: "form-select form-select-sm", include_blank: "選択してください" %>
207
+ </div>
205
- <%= f.text_field :balance, class: "form-control form-control-sm", placeholder:"例) 1000" %>
208
+ <%= f.text_field :balance, placeholder:"例) 1000" ,id: "input-balance_0"%>
206
- <input type="button" value="削除" class="del">
209
+ <button id="0" onclick="deleteBtn(this)">削除</button>
207
210
  </div>
211
+ <%#input type="button" value="削除" id="delete-btn"%>
208
- <input type="button" value="追加" id="add">
212
+ <input type="button" value="追加" id="add-btn">
209
213
  </div>
214
+
215
+
210
216
  <div class='form-bottom-text'>
211
217
  <%= f.submit "次へ" ,class: "btn btn-outline-secondary"%>
212
218
  </div>
213
- </div>
219
+
214
- </div>
215
- </div>
216
220
  <% end %>
217
221
  </div>
218
222
  ```
219
223
 
220
224
  ```javascript
225
+ const i = 1 ;
226
+ const minCount = 0;
227
+ const maxCount = 5;
228
+
229
+ //追加ボタン
230
+ function addForm() {
231
+ const add = document.getElementById("add-btn");
221
- document.addEventListener('click',(e)=>{
232
+ add.addEventListener("click", () => {
233
+ //フォーム生成
234
+ const select = document.getElementById("selectbox_0");
222
- const t=e.target;
235
+ const select_copy = select.cloneNode(true);
236
+ select_copy.id = 'selectbox_' + i;
237
+ const input = document.getElementById("input-balance_0");
238
+ const input_copy = input.cloneNode(true);
239
+ input_copy.id = 'input-balance_' + i;
223
- if(t.matches('#add')){
240
+ input_copy.value = ''
241
+ if (i < maxCount) {
224
- const d=document.querySelector('.form-field');
242
+ const parent = document.getElementById('form-field');
225
-
226
- d.parentNode.insertBefore(d.cloneNode(true),d.nextElementSibling);
243
+ parent.appendChild(select_copy);
244
+ parent.appendChild(input_copy);
227
- }
245
+ }
246
+
247
+ //削除ボタン生成
248
+ const button_data = document.createElement('button');
249
+ button_data.id = i;
250
+ button_data.onclick = function(){deleteBtn(this);}
228
- if(t.matches('.del')){
251
+ button_data.innerHTML = '削除';
252
+ if (i < maxCount) {
229
- t.closest('.form-field')?.remove();
253
+ const parent = document.getElementById('form-field');
254
+ var input_area = document.getElementById(select_copy.id);
255
+ parent.appendChild(button_data);
230
- }
256
+ }
257
+ i++ ;
231
- });
258
+ });
259
+ };
260
+ window.addEventListener('load', addForm);
261
+
262
+
263
+ //削除ボタン
264
+ window.deleteBtn = function(target){
265
+ const target_id = target.id;
266
+ const parent = document.getElementById('form-field');
267
+ const slt_id = document.getElementById('selectbox_' + target_id);
268
+ const ipt_id = document.getElementById('input-balance_' + target_id);
269
+ const tgt_id = document.getElementById(target_id);
270
+ if (target_id > minCount){
271
+ parent.removeChild(slt_id);
272
+ parent.removeChild(ipt_id);
273
+ parent.removeChild(tgt_id);
274
+ }
275
+ }
232
276
  ```
233
277
 
234
278
  何卒よろしくお願いいたします。

1

コードの修正

2022/08/28 03:15

投稿

happy
happy

スコア13

test CHANGED
File without changes
test CHANGED
@@ -29,7 +29,122 @@
29
29
 
30
30
  - app/controllers/users/registrations_controlntroller.rb
31
31
 
32
+ ```ruby
33
+ # frozen_string_literal: true
34
+
35
+ class Users::RegistrationsController < Devise::RegistrationsController
36
+ # before_action :configure_sign_up_params, only: [:create]
37
+ # before_action :configure_account_update_params, only: [:update]
38
+
39
+ def new
40
+ @user = User.new
41
+ end
42
+
43
+ #1ページ目の情報をsessionに保持
44
+ def create
45
+ @user = User.new(sign_up_params)
46
+ render :new and return unless @user.valid?
47
+
48
+ session['devise.regist_data'] = { user: @user.attributes }
49
+ session['devise.regist_data'][:user]['password'] = params[:user][:password]
50
+ @assettable = @user.build_assettable
51
+ render :new_assettable
52
+ end
53
+
54
+ #1, 2ページ目の情報をsessionに保持
55
+ def create_assettable
56
+ @user = User.new(session['devise.regist_data']['user'])
57
+ @assettable = Assettable.new(assettable_params)
58
+ render :new_assettable and return unless @assettable.valid?
59
+
60
+ session['devise.regist_data']['assettable'] = { assettable: @assettable.attributes }
61
+ @debttable = @user.build_debttable
62
+ render :new_debttable
63
+ end
64
+
65
+ #1〜3ページの情報を保存
66
+ def create_debttable
67
+ @user = User.new(session['devise.regist_data']['user'])
32
- [![Image from Gyazo](https://i.gyazo.com/ed0dff21e14c7a03d387ea4ba295249b.png)](https://gyazo.com/ed0dff21e14c7a03d387ea4ba295249b)
68
+ @assettable = Assettable.new(session['devise.regist_data']['assettable']['assettable'])
69
+ @user.build_assettable(@assettable.attributes)
70
+ @user.save
71
+ @debttable = Debttable.new(debttable_params)
72
+ render :new_debttable and return unless @debttable.valid?
73
+
74
+ @user.build_debttable(@debttable.attributes)
75
+ @user.save
76
+
77
+ session['devise.regist_data'].clear
78
+ sign_in(:user, @user)
79
+ end
80
+
81
+ private
82
+
83
+ def assettable_params
84
+ params.require(:assettable).permit(:balance, :list_id)
85
+ end
86
+
87
+ def debttable_params
88
+ params.require(:debttable).permit(:balance, :list_id)
89
+ end
90
+
91
+ # GET /resource/sign_up
92
+ # def new
93
+ # super
94
+ # end
95
+
96
+ # POST /resource
97
+ # def create
98
+ # super
99
+ # end
100
+
101
+ # GET /resource/edit
102
+ # def edit
103
+ # super
104
+ # end
105
+
106
+ # PUT /resource
107
+ # def update
108
+ # super
109
+ # end
110
+
111
+ # DELETE /resource
112
+ # def destroy
113
+ # super
114
+ # end
115
+
116
+ # GET /resource/cancel
117
+ # Forces the session data which is usually expired after sign
118
+ # in to be expired now. This is useful if the user wants to
119
+ # cancel oauth signing in/up in the middle of the process,
120
+ # removing all OAuth session data.
121
+ # def cancel
122
+ # super
123
+ # end
124
+
125
+ # protected
126
+
127
+ # If you have extra params to permit, append them to the sanitizer.
128
+ # def configure_sign_up_params
129
+ # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
130
+ # end
131
+
132
+ # If you have extra params to permit, append them to the sanitizer.
133
+ # def configure_account_update_params
134
+ # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
135
+ # end
136
+
137
+ # The path used after sign up.
138
+ # def after_sign_up_path_for(resource)
139
+ # super(resource)
140
+ # end
141
+
142
+ # The path used after sign up for inactive accounts.
143
+ # def after_inactive_sign_up_path_for(resource)
144
+ # super(resource)
145
+ # end
146
+ end
147
+ ```
33
148
 
34
149
  ### ターミナル
35
150
  - create_assettableメソッドを `binding.pry` でデバックした結果です。
@@ -47,13 +162,29 @@
47
162
 
48
163
  ### ルーティング
49
164
 
165
+ ```ruby
166
+ Rails.application.routes.draw do
167
+ root to: 'top#index'
168
+ resources :books, only: :index
169
+
170
+ devise_for :users, controllers: {
171
+ registrations: 'users/registrations'
172
+ }
173
+ devise_scope :user do
174
+ get 'assettables', to: 'users/registrations#new_assettable'
50
- [![Image from Gyazo](https://i.gyazo.com/2389130219c9e1532edb3c9d9e6ac390.png)](https://gyazo.com/2389130219c9e1532edb3c9d9e6ac390)
175
+ post 'assettables', to: 'users/registrations#create_assettable'
176
+ get 'debttables', to: 'users/registrations#new_debttable'
177
+ post 'debttables', to: 'users/registrations#create_debttable'
178
+ end
179
+
180
+ end
181
+ ```
51
182
 
52
183
  ### コード
53
184
 
54
185
  - 2ページ目のビュー(3ページ目も同様です)
55
186
 
56
- ```ruby
187
+ ```r
57
188
  <div class="wrapper">
58
189
  <%= render "devise/shared/header" %>
59
190