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

回答編集履歴

3

コードの改善方法について追記

2021/12/04 12:31

投稿

okuramasafumi
okuramasafumi

スコア117

answer CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ~~意図と達成するには、該当のif文を`if @mandalarts.blank?`にするとよいでしょう。~~
4
4
 
5
+ 当初の想定は私の勘違いでした。改めて状況を確認してみたのですが、やはり @winderboum さんがおっしゃるようにテスト環境にのみすでに1件または2件のデータが保存されてしまっているとしか考えられません。
6
+
7
+ もうちょっと深掘りすると、この`index`メソッドは`GET`でアクセスされるものであるにも関わらず、「データがないならデータを作る」という振る舞いをしてしまいます。これは冪等性を満たしていません。また、すでにデータが1件でも存在するなら何もしませんが、それでは「データが9件必要である」という要件を満たせません。
8
+ このような「一定の初期データが必要である」という状況では、開発環境ではseedと呼ばれる仕組みが、テスト環境ではfixtureまたはfactoryと呼ばれる仕組みが、それぞれ使われます。
9
+
10
+ seedについては
11
+ [公式ガイド](https://railsguides.jp/active_record_migrations.html#%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%82%B7%E3%83%BC%E3%83%89%E3%83%87%E3%83%BC%E3%82%BF)を参照してください。
12
+
13
+ factoryについてはすでに利用されているようですが、system specの`before`ブロックで`FactoryBot.create_list :mandalart, 9)`を実行することで毎回9件のレコードを保存できます。
14
+
15
+ ついでに、本番環境では基本的に1度保存したデータは削除されないため、手動で9件のデータを作成することで問題ないかと思われます。
16
+
5
17
  【追記】
6
18
  エラーがなぜ15行目で起きているかについて説明します。
7
19
  Rubyでは`[][0..2] # => []`という実行結果になります。これはつまり、「空の配列に対して範囲アクセスをした場合、範囲に0が含まれていると空の配列が返ってくる」ということです。一方、範囲が0を含まないと`[][3..5] # => nil`のようになります。

2

回答が間違っていたのでいったん取り消し線で訂正

2021/12/04 12:31

投稿

okuramasafumi
okuramasafumi

スコア117

answer CHANGED
@@ -1,6 +1,6 @@
1
- `if @mandalarts == []`の行が間違っています。`@mandalarts = Mandalart.all`で得られるオブジェクトは配列**ではなく**、`ActiveRecord::Relation`というオブジェクトです。ですので、このif文は常にfalseとなります。
1
+ ~~`if @mandalarts == []`の行が間違っています。`@mandalarts = Mandalart.all`で得られるオブジェクトは配列**ではなく**、`ActiveRecord::Relation`というオブジェクトです。ですので、このif文は常にfalseとなります。 ~~
2
2
 
3
- 意図と達成するには、該当のif文を`if @mandalarts.blank?`にするとよいでしょう。
3
+ ~~意図と達成するには、該当のif文を`if @mandalarts.blank?`にするとよいでしょう。~~
4
4
 
5
5
  【追記】
6
6
  エラーがなぜ15行目で起きているかについて説明します。

1

エラーが起こる箇所がわかりにくい点について追記

2021/12/04 12:04

投稿

okuramasafumi
okuramasafumi

スコア117

answer CHANGED
@@ -1,3 +1,8 @@
1
1
  `if @mandalarts == []`の行が間違っています。`@mandalarts = Mandalart.all`で得られるオブジェクトは配列**ではなく**、`ActiveRecord::Relation`というオブジェクトです。ですので、このif文は常にfalseとなります。
2
2
 
3
- 意図と達成するには、該当のif文を`if @mandalarts.blank?`にするとよいでしょう。
3
+ 意図と達成するには、該当のif文を`if @mandalarts.blank?`にするとよいでしょう。
4
+
5
+ 【追記】
6
+ エラーがなぜ15行目で起きているかについて説明します。
7
+ Rubyでは`[][0..2] # => []`という実行結果になります。これはつまり、「空の配列に対して範囲アクセスをした場合、範囲に0が含まれていると空の配列が返ってくる」ということです。一方、範囲が0を含まないと`[][3..5] # => nil`のようになります。
8
+ このため、最初のループではエラーは起きず(しかし要素がないので何も起きない)、2回目のループでエラーが起きます。