質問編集履歴

3

解決時のソースと検証結果を追記

2020/05/16 01:49

投稿

_Taturon_
_Taturon_

スコア17

test CHANGED
File without changes
test CHANGED
@@ -300,7 +300,7 @@
300
300
 
301
301
 
302
302
 
303
- ### 追記1:sourceモデルに既出のデータがあってもそれと紐付けられません
303
+ ### 追記1sourceモデルに既出のデータがあってもそれと紐付けられません
304
304
 
305
305
  次のように実装することで、関連付けたデータの保存はできるようになりました。ありがとうございます。
306
306
 
@@ -473,3 +473,151 @@
473
473
  ```
474
474
 
475
475
  おそらく```@memo.sources.find_or_initialize_by```としているので、sourceモデル全体から```find_by```しているのではなく、関連付けられたsourceから```find_by```してしまっているのが原因と思うのですが、解決方法が分かりません。何かアドバイスを頂けないでしょうか?
476
+
477
+
478
+
479
+ ### 追記2:解決しました
480
+
481
+ winterboumさんのアドバイス通り、下記のように実装することで、重複しているurlはそのままに新規のみ保存できるようになりました。
482
+
483
+ ありがとうございました!
484
+
485
+ ```rb
486
+
487
+ #memosコントローラー
488
+
489
+ class MemosController < ApplicationController
490
+
491
+
492
+
493
+  ・
494
+
495
+  ・
496
+
497
+  ・
498
+
499
+
500
+
501
+ def new
502
+
503
+ @memo = Memo.new
504
+
505
+ @source = @memo.sources.build
506
+
507
+ end
508
+
509
+
510
+
511
+ def create
512
+
513
+ @memo = Memo.new(memo_params.slice(:word, :content, :synonym, :tag_list))
514
+
515
+ if @memo.save
516
+
517
+ @source = Source.find_or_create_by(url: memo_params[:url])
518
+
519
+ @memo.sources << @source
520
+
521
+ flash[:notice] = "新しいMemoを作成しました!"
522
+
523
+ redirect_to root_url
524
+
525
+ else
526
+
527
+ flash.now[:alert] = "無効な送信です"
528
+
529
+ render :new
530
+
531
+ end
532
+
533
+ end
534
+
535
+
536
+
537
+  ・
538
+
539
+  ・
540
+
541
+  ・
542
+
543
+
544
+
545
+ private
546
+
547
+
548
+
549
+ def memo_params
550
+
551
+ params.require(:memo).permit(
552
+
553
+ :word,
554
+
555
+ :content,
556
+
557
+ :synonym,
558
+
559
+ :tag_list,
560
+
561
+ :url
562
+
563
+ )
564
+
565
+ end
566
+
567
+
568
+
569
+ end
570
+
571
+ ```
572
+
573
+ ```console
574
+
575
+ 異なるmemoに同じurlを関連付けて保存した場合
576
+
577
+ > SourceMap.all
578
+
579
+ SourceMap Load (0.5ms) SELECT "source_maps".* FROM "source_maps" LIMIT ? [["LIMIT", 11]]
580
+
581
+ => #<ActiveRecord::Relation [
582
+
583
+ #<SourceMap id: 1, memo_id: 1, source_id: 1, created_at: "2020-05-16 01:35:29", updated_at: "2020-05-16 01:35:29">,
584
+
585
+ #<SourceMap id: 2, memo_id: 2, source_id: 1, created_at: "2020-05-16 01:35:38", updated_at: "2020-05-16 01:35:38">]>
586
+
587
+ > Source.all
588
+
589
+ (1.0ms) SELECT sqlite_version(*)
590
+
591
+ Source Load (0.4ms) SELECT "sources".* FROM "sources" LIMIT ? [["LIMIT", 11]]
592
+
593
+ => #<ActiveRecord::Relation [
594
+
595
+ #<Source id: 1, url: "https://rails.densan-labs.net/form/relation_regist...", created_at: "2020-05-16 01:35:29", updated_at: "2020-05-16 01:35:29">]>
596
+
597
+
598
+
599
+ 続けて異なるmemoを異なるurlで関連付けて保存した場合
600
+
601
+ > SourceMap.all
602
+
603
+ SourceMap Load (0.2ms) SELECT "source_maps".* FROM "source_maps" LIMIT ? [["LIMIT", 11]]
604
+
605
+ => #<ActiveRecord::Relation [
606
+
607
+ #<SourceMap id: 1, memo_id: 1, source_id: 1, created_at: "2020-05-16 01:35:29", updated_at: "2020-05-16 01:35:29">,
608
+
609
+ #<SourceMap id: 2, memo_id: 2, source_id: 1, created_at: "2020-05-16 01:35:38", updated_at: "2020-05-16 01:35:38">,
610
+
611
+ #<SourceMap id: 3, memo_id: 3, source_id: 2, created_at: "2020-05-16 01:37:04", updated_at: "2020-05-16 01:37:04">]>
612
+
613
+ > Source.all
614
+
615
+ Source Load (0.2ms) SELECT "sources".* FROM "sources" LIMIT ? [["LIMIT", 11]]
616
+
617
+ => #<ActiveRecord::Relation [
618
+
619
+ #<Source id: 1, url: "https://rails.densan-labs.net/form/relation_regist...", created_at: "2020-05-16 01:35:29", updated_at: "2020-05-16 01:35:29">,
620
+
621
+ #<Source id: 2, url: "https://teratail.com/questions/261655#", created_at: "2020-05-16 01:37:04", updated_at: "2020-05-16 01:37:04">]>
622
+
623
+ ```

2

誤字を修正

2020/05/16 01:49

投稿

_Taturon_
_Taturon_

スコア17

test CHANGED
File without changes
test CHANGED
@@ -432,7 +432,7 @@
432
432
 
433
433
  ```console
434
434
 
435
- 以下フォームから同じ異なるmemoに対し同じurlを登録した場合のモデル内データ
435
+ 以下フォームから異なるmemoに対し同じurlを登録した場合のモデル内データ
436
436
 
437
437
 
438
438
 
@@ -472,4 +472,4 @@
472
472
 
473
473
  ```
474
474
 
475
- おそらく```@memo.sources.find_or_initialize_by```としているので、sourceモデル全体から```find_by```しているのではなく、関連付けられたsourceから```find_by```してしまっているのが原因と思うのですが、解決方法が分かりません。
475
+ おそらく```@memo.sources.find_or_initialize_by```としているので、sourceモデル全体から```find_by```しているのではなく、関連付けられたsourceから```find_by```してしまっているのが原因と思うのですが、解決方法が分かりません。何かアドバイスを頂けないでしょうか?

1

関連付けに関して追記しました

2020/05/15 23:04

投稿

_Taturon_
_Taturon_

スコア17

test CHANGED
File without changes
test CHANGED
@@ -297,3 +297,179 @@
297
297
 
298
298
 
299
299
  初歩的な質問ですが、どなたかご回答の程、お願い申し上げます。
300
+
301
+
302
+
303
+ ### 追記1:sourceモデルに既出のデータがあってもそれと紐付けられません
304
+
305
+ 次のように実装することで、関連付けたデータの保存はできるようになりました。ありがとうございます。
306
+
307
+ ```erb
308
+
309
+ <!--フォームパーシャル-->
310
+
311
+ <%= form_with model: @memo, local: true do |f| %>
312
+
313
+
314
+
315
+  ・
316
+
317
+  ・
318
+
319
+  ・
320
+
321
+
322
+
323
+ <div class="form-group">
324
+
325
+ <%= f.label :url, "出典(URL)" %>
326
+
327
+ <%= f.url_field :url, class: "form-control",
328
+
329
+ placeholder: "出典元のURLを記入して下さい" %>
330
+
331
+ </div>
332
+
333
+ <div class="form-group">
334
+
335
+ <%= f.submit yield(:btn_message), class: "btn btn-success btn-lg btn-block" %>
336
+
337
+ </div>
338
+
339
+ <% end %>
340
+
341
+ ```
342
+
343
+ ```rb
344
+
345
+ #memosコントローラー
346
+
347
+ class MemosController < ApplicationController
348
+
349
+
350
+
351
+  ・
352
+
353
+  ・
354
+
355
+  ・
356
+
357
+
358
+
359
+ def new
360
+
361
+ @memo = Memo.new
362
+
363
+ @source = @memo.sources.build
364
+
365
+ end
366
+
367
+
368
+
369
+ def create
370
+
371
+ @memo = Memo.new(memo_params.slice(:word, :content, :synonym, :tag_list))
372
+
373
+ if @memo.save
374
+
375
+ @source = @memo.sources.find_or_initialize_by(url: memo_params[:url])
376
+
377
+ @memo.sources << @source
378
+
379
+ flash[:notice] = "新しいMemoを作成しました!"
380
+
381
+ redirect_to root_url
382
+
383
+ else
384
+
385
+ flash.now[:alert] = "無効な送信です"
386
+
387
+ render :new
388
+
389
+ end
390
+
391
+ end
392
+
393
+
394
+
395
+  ・
396
+
397
+  ・
398
+
399
+  ・
400
+
401
+
402
+
403
+ private
404
+
405
+
406
+
407
+ def memo_params
408
+
409
+ params.require(:memo).permit(
410
+
411
+ :word,
412
+
413
+ :content,
414
+
415
+ :synonym,
416
+
417
+ :tag_list,
418
+
419
+ :url
420
+
421
+ )
422
+
423
+ end
424
+
425
+
426
+
427
+ end
428
+
429
+ ```
430
+
431
+ しかし、find_or_initialize_byを使用しても、既出のurlがあってもそれと紐付けられず、同じurlがsourceモデルに新規保存されそちらと紐付けられてしまいます。
432
+
433
+ ```console
434
+
435
+ 以下フォームから同じ異なるmemoに対し同じurlを登録した場合のモデル内データ
436
+
437
+
438
+
439
+ 同じurlであってもfind_byされずに新規登録されてしまう
440
+
441
+ > Source.all
442
+
443
+ (0.8ms) SELECT sqlite_version(*)
444
+
445
+ Source Load (0.5ms) SELECT "sources".* FROM "sources" LIMIT ? [["LIMIT", 11]]
446
+
447
+ => #<ActiveRecord::Relation [
448
+
449
+ #<Source id: 1, url: "https://rails.densan-labs.net/form/relation_regist...", created_at: "2020-05-15 22:31:03", updated_at: "2020-05-15 22:31:03">,
450
+
451
+ #<Source id: 2, url: "https://rails.densan-labs.net/form/relation_regist...", created_at: "2020-05-15 22:31:11", updated_at: "2020-05-15 22:31:11">]>
452
+
453
+
454
+
455
+ 関連付けも、本来なら
456
+
457
+ SourceMap id: 1, memo_id: 1, source_id: 1
458
+
459
+ SourceMap id: 1, memo_id: 2, source_id: 1
460
+
461
+ となって欲しいが、新規登録されたsource_id: 2と関連付けられてしまう
462
+
463
+ > SourceMap.all
464
+
465
+ SourceMap Load (0.2ms) SELECT "source_maps".* FROM "source_maps" LIMIT ? [["LIMIT", 11]]
466
+
467
+ => #<ActiveRecord::Relation [
468
+
469
+ #<SourceMap id: 1, memo_id: 1, source_id: 1, created_at: "2020-05-15 22:31:03", updated_at: "2020-05-15 22:31:03">,
470
+
471
+ #<SourceMap id: 2, memo_id: 2, source_id: 2, created_at: "2020-05-15 22:31:11", updated_at: "2020-05-15 22:31:11">]>
472
+
473
+ ```
474
+
475
+ おそらく```@memo.sources.find_or_initialize_by```としているので、sourceモデル全体から```find_by```しているのではなく、関連付けられたsourceから```find_by```してしまっているのが原因と思うのですが、解決方法が分かりません。