teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

7

細かい説明を追加

2019/04/10 01:22

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
@@ -1,5 +1,5 @@
1
1
  ### 下記Modelを定義していて
2
- ```
2
+ ```ruby:
3
3
  class Maker < ApplicationRecord
4
4
  has_many :notes, inverse_of: :maker
5
5
  validates :name, presence: true, uniqueness: true
@@ -28,38 +28,41 @@
28
28
  end
29
29
  ```
30
30
 
31
- ### コントローラ上で下記を実現したです
31
+ ### 下記データが登録されてる時に
32
+ ```
33
+ @Maker Table @Tag Table @Note Table
34
+ id | name id | name id | name | maker_id
35
+ ------------ ------------- -----------------------
36
+ 1 | maker1 1 | tag1 1 | note1 | 1
37
+ 2 | maker2 2 | tag2 2 | note2 | 2
38
+ 3 | tag3
32
39
 
40
+ @TagRelation Table
41
+ id | note_id | tag_id
42
+ -----------------------
43
+ 1 | 1 | 1
44
+ 2 | 2 | 2
45
+ 3 | 2 | 3
33
46
  ```
34
- params0 = {
35
- name: 'note0',
36
- maker_attributes: {
37
- name: 'maker',
38
- },
39
- tags_attributes: [
40
- {name: 'tag0'},
41
- {name: 'tag1'},
42
- ],
43
- }
44
- ```
45
- を宣言して`Note.new(params0).save`した後に、 下記パラメータも `save` したいのです。
46
47
 
48
+
49
+ ### コントローラ上で(permit後の)下記パラメータでNoteにsaveしたい
50
+
47
- ```
51
+ ```ruby:
48
- params1 = {
52
+ params = {
49
- name: 'note1',
53
+ name: 'note3',
50
54
  maker_attributes: {
51
- name: 'maker',
55
+ name: 'maker1',
52
56
  },
53
57
  tags_attributes: [
54
58
  {name: 'tag1'},
55
- {name: 'tag2'},
59
+ {name: 'tag4'},
56
60
  ],
57
61
  }
58
62
  ```
59
- 具体的には`Note.new(params1).save`です!
60
63
 
64
+
61
- ### バリデーションエラー
65
+ ### 発生するバリデーションエラー
62
- 下記が発生します。
63
66
  ```
64
67
  {
65
68
  :"maker.name" => ["has already been taken"]
@@ -67,8 +70,27 @@
67
70
  }
68
71
  ```
69
72
 
70
- ### 質問したいこと
73
+ ### 具体的に実行したいこと
74
+ `Note.new(params).save` すると、上記のバリデーションエラーが発生します。
75
+ ※ `maker.name` も `tags[x].name` も `uniqueness: true` なので当然ですが。。。
76
+
77
+ 実施したいのは、`Maker` `Tag` の両テーブルに登録済のデータ(`name`カラム)があれば、
78
+ レコードを増やす事なく、勝手に`Note`からリレーションを貼ってもらいたいのです。
79
+
80
+ 動作イメージとしては、下記のようになります。
81
+ ```ruby
82
+ note = Note.new(params)
83
+ # バリデーションに成功する
84
+ note.valid? # => true
85
+
86
+ # Makerは登録済のレコードなので、対象のレコードを持ってくる
87
+ note.maker # => Maker(id: 1, name: 'maker1')
88
+ # tags[0]は登録済のレコードなので対象を持ってくるが、 tags[1]は新規
71
- `Note` から `belongs_to :maker` リレーションテーブルを使って `has_one` にするのも考えているのですが、結局は `tags` に対するエラーが解決できず・・・。
89
+ note.tags # => [Tag(id: 1, name: 'tag1'), Tag(id: nil, name: 'tag4')]
90
+
72
-
91
+ note.save # => true
92
+ ```
93
+
94
+ 現状、考えられるのは `Note` の `before_validation` で各モデルに `find_or_initialize` するしかないかなと考えているのですが、
73
- `accepts_nested_attributes_for` を使っうまくかず。。。
95
+ `validates` や `accepts_nested_attributes_for` に有効なオプションや、他に手法があれば教えていただきたいです!
74
- どうても `uniqueness` 制約にかかるので、教えていただきたく :bow:
96
+ よろしくおねがいします :bow:

6

インデックス間違い

2019/04/10 01:22

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
@@ -63,7 +63,7 @@
63
63
  ```
64
64
  {
65
65
  :"maker.name" => ["has already been taken"]
66
- :"tags[1].name" => ["has already been taken"]
66
+ :"tags[0].name" => ["has already been taken"]
67
67
  }
68
68
  ```
69
69
 

5

バリデーションエラーの詳細を記述

2019/04/05 02:52

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  }
44
44
  ```
45
- を`Note.new(params0).save`した後に、
45
+ 宣言して`Note.new(params0).save`した後に、 下記パラメータも `save` したいのです。
46
46
 
47
47
  ```
48
48
  params1 = {
@@ -56,9 +56,17 @@
56
56
  ],
57
57
  }
58
58
  ```
59
- 上記も`Note.new(params1).save`したいのです!
59
+ 具体的には`Note.new(params1).save`です!
60
- → バリデーションエラーとして、 `{:"tags[1].name" => ["has already been taken"]}` が発生します。
61
60
 
61
+ ### バリデーションエラー
62
+ 下記が発生します。
63
+ ```
64
+ {
65
+ :"maker.name" => ["has already been taken"]
66
+ :"tags[1].name" => ["has already been taken"]
67
+ }
68
+ ```
69
+
62
70
  ### 質問したいこと
63
71
  `Note` から `belongs_to :maker` を リレーションテーブルを使って `has_one` にするのも考えているのですが、結局は `tags` に対するエラーが解決できず・・・。
64
72
 

4

詳細を記述

2019/04/05 02:51

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
@@ -18,16 +18,20 @@
18
18
 
19
19
  class Note < ApplicationRecord
20
20
  belongs_to :maker
21
+ accepts_nested_attributes_for :maker
22
+
21
23
  has_many :relations, class_name: 'TagRelation'
22
- has_many :tag, through: :relations, source: :tag
24
+ has_many :tags, through: :relations, source: :tag
25
+ accepts_nested_attributes_for :tags
26
+
23
27
  validates :name, presence: true, uniqueness: true
24
28
  end
25
29
  ```
26
30
 
27
- ### 下記を実現したいです
31
+ ### コントローラ上で下記を実現したいです
28
32
 
29
33
  ```
30
- Note.new({
34
+ params0 = {
31
35
  name: 'note0',
32
36
  maker_attributes: {
33
37
  name: 'maker',
@@ -36,11 +40,12 @@
36
40
  {name: 'tag0'},
37
41
  {name: 'tag1'},
38
42
  ],
39
- }).save
43
+ }
40
44
  ```
41
- した後に、
45
+ を`Note.new(params0).save`した後に、
46
+
42
47
  ```
43
- Note.new({
48
+ params1 = {
44
49
  name: 'note1',
45
50
  maker_attributes: {
46
51
  name: 'maker',
@@ -49,12 +54,13 @@
49
54
  {name: 'tag1'},
50
55
  {name: 'tag2'},
51
56
  ],
52
- }).save
57
+ }
53
58
  ```
54
- したいのです!
59
+ 上記も`Note.new(params1).save`したいのです!
60
+ → バリデーションエラーとして、 `{:"tags[1].name" => ["has already been taken"]}` が発生します。
55
61
 
56
62
  ### 質問したいこと
57
63
  `Note` から `belongs_to :maker` を リレーションテーブルを使って `has_one` にするのも考えているのですが、結局は `tags` に対するエラーが解決できず・・・。
58
64
 
59
- `accepts_nested_attributes_for` を使えばうまくいなと思っているのですが、
65
+ `accepts_nested_attributes_for` を使ってうまくいかず。。。
60
66
  どうしても `uniqueness` 制約にかかるので、教えていただきたく :bow:

3

タグ追加

2019/04/05 02:36

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
File without changes

2

タイトル変更

2019/04/04 09:48

投稿

aa37971
aa37971

スコア24

title CHANGED
@@ -1,1 +1,1 @@
1
- リレーションのあるマスターテーブルを同時に追加したい
1
+ 【Rails】リレーションのあるマスターテーブルを同時に追加したい
body CHANGED
File without changes

1

タグ追加

2019/04/04 01:49

投稿

aa37971
aa37971

スコア24

title CHANGED
File without changes
body CHANGED
File without changes