人生楽しんで反撃だ!

日々プログラミングで学んだことをアウトプットしたり、人生楽しむための考察をしたりします。

`attach' が使えないよと怒られた話

フリマアプリに大苦戦してるヲキヨです。

テストコード地獄から抜け出したい!!

しかしプルリクエストを送ると

「example6追加してください^^」

鬼ですか!!!www

テックキャンプの人はドSなんじゃないかと思えてきた・・・・(まぁあの社長だからな・・・・)

テストコードを実行すると出てくるエラー

-----------------------------------------------

1) Item アイテムの保存 アイテムが保存できる場合 全ての情報が存在すれば登録できる
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

-----------------------------------------------

`attach'が使えない。

結論から言うとimageのアソシエーションにbelongs_toを使っているからでした。

imageはActiveStorageで管理されているためアソシエーションはhas_one_attached

にしなければいけないとのことでした。

 

app/modes/item.rb

 
class Item < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :user
belongs_to :image ←ここがbelongs_toになっている
belongs_to :category
belongs_to :condition
belongs_to :pay
belongs_to :area
belongs_to :day
 
with_options presence: true do
validates :name, presence: true
validates :text, presence: true
validates :category_id
validates :condition_id
validates :pay_id
validates :area_id
validates :day_id
validates :price, numericality: {only_integer: true, greater_than_or_equal_to: 300, less_than_or_equal_to: 9999999}
end
end

imageのアソシエーションにbelongs_toを使っている

 

spec/factory/items.rb

 
FactoryBot.define do

factory :item do
name {Faker::Name.name}
text {"1234"}
category_id {2}
condition_id {2}
pay_id {2}
area_id {2}
day_id {2}
price{1111111}
association :user

after(:build) do |item|
item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')
end
end
end
 

imageを関連づけているattachが使えないと言われる。

 

メンターさんでも少し考えるくらい珍しいエラーでした。

(それくらいの凡ミスってことorz)

 

spec/modes/item_spec.rb

require 'rails_helper'

RSpec.describe Item, type: :model do
before do
@item = FactoryBot.build(:item)
end
 
describe 'アイテムの保存' do
context "アイテムが保存できる場合" do
it "全ての情報が存在すれば登録できる" do
expect(@item).to be_valid
end
end
 
context "アイテムが保存できない場合" do
it "・・・imageが空では登録できない" do
@item.name = ""
@item.valid?
expect(@item.errors.full_messages).to include("Name can't be blank")
end
it "nameが空だとアイテムは保存できない" do
@item.name = ""
@item.valid?
expect(@item.errors.full_messages).to include("Name can't be blank")
end

it "商品の説明がないとアイテムは保存できない" do
@item.text = ""
@item.valid?
expect(@item.errors.full_messages).to include("Text can't be blank")
end

it "カテゴリーの情報がないとアイテムは保存できない" do
@item.category_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Category can't be blank")
end
it "・・・カテゴリーの情報は1以外でないと登録できない" do
@item.category_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Category can't be blank")
end

it "商品の状態の情報がないとアイテムは保存できない" do
@item.condition_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Condition can't be blank")
end
it "・・・商品の状態の情報は1以外でないと登録できない" do
@item.condition_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Condition can't be blank")
end
 
it "配送料の負担の情報がないとアイテムは保存できない" do
@item.pay_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Pay can't be blank")
end
it "・・・配送料の負担の情報は1以外でないと登録できない" do
@item.pay_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Pay can't be blank")
end
it "発送元の地域の情報がないとアイテムは保存できない" do
@item.area_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Area can't be blank")
end
it "・・・発送元の地域の情報は1以外でないと登録できない" do
@item.area_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Area can't be blank")
end

it "発送までの日数の情報がないとアイテムは保存できない" do
@item.day_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Day can't be blank")
end
it "・・・発送までの日数は1以外でないと登録できない" do
@item.day_id = ""
@item.valid?
expect(@item.errors.full_messages).to include("Day can't be blank")
end

it "価格の情報がないとアイテムは保存できない" do
@item.price = ""
@item.valid?
expect(@item.errors.full_messages).to include("Price can't be blank")
end
it "価格の範囲がの¥300~¥9,999,999の間でないとアイテムは保存できない" do
@item.price = "1"
@item.valid?
expect(@item.errors.full_messages).to include("Price must be greater than or equal to 300")
end
it "価格が299円以下だと出品できない" do
@item.price = "1"
@item.valid?
expect(@item.errors.full_messages).to include("Price must be greater than or equal to 300")
end
it "価格が10000000円以上だと出品できない" do
@item.price = "10000001"
@item.valid?
expect(@item.errors.full_messages).to include("Price must be less than or equal to 9999999")
end
it "価格は半角数字のみでないとアイテムは保存できない" do
@item.price = "てすと"
@item.valid?
expect(@item.errors.full_messages).to include("Price is not a number")
end
end
end
end

 

エラー文全文

Item
アイテムの保存
アイテムが保存できる場合
全ての情報が存在すれば登録できる (FAILED - 1)
アイテムが保存できない場合
・・・imageが空では登録できない (FAILED - 2)
nameが空だとアイテムは保存できない (FAILED - 3)
商品の説明がないとアイテムは保存できない (FAILED - 4)
カテゴリーの情報がないとアイテムは保存できない (FAILED - 5)
・・・カテゴリーの情報は1以外でないと登録できない (FAILED - 6)
商品の状態の情報がないとアイテムは保存できない (FAILED - 7)
・・・商品の状態の情報は1以外でないと登録できない (FAILED - 8)
配送料の負担の情報がないとアイテムは保存できない (FAILED - 9)
・・・配送料の負担の情報は1以外でないと登録できない (FAILED - 10)
発送元の地域の情報がないとアイテムは保存できない (FAILED - 11)
・・・発送元の地域の情報は1以外でないと登録できない (FAILED - 12)
発送までの日数の情報がないとアイテムは保存できない (FAILED - 13)
・・・発送までの日数は1以外でないと登録できない (FAILED - 14)
価格の情報がないとアイテムは保存できない (FAILED - 15)
価格の範囲がの¥300~¥9,999,999の間でないとアイテムは保存できない (FAILED - 16)
価格が299円以下だと出品できない (FAILED - 17)
価格が10000000円以上だと出品できない (FAILED - 18)
価格は半角数字のみでないとアイテムは保存できない (FAILED - 19)

Failures:

1) Item アイテムの保存 アイテムが保存できる場合 全ての情報が存在すれば登録できる
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

2) Item アイテムの保存 アイテムが保存できない場合 ・・・imageが空では登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

3) Item アイテムの保存 アイテムが保存できない場合 nameが空だとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

4) Item アイテムの保存 アイテムが保存できない場合 商品の説明がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

5) Item アイテムの保存 アイテムが保存できない場合 カテゴリーの情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

6) Item アイテムの保存 アイテムが保存できない場合 ・・・カテゴリーの情報は1以外でないと登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

7) Item アイテムの保存 アイテムが保存できない場合 商品の状態の情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

8) Item アイテムの保存 アイテムが保存できない場合 ・・・商品の状態の情報は1以外でないと登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

9) Item アイテムの保存 アイテムが保存できない場合 配送料の負担の情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

10) Item アイテムの保存 アイテムが保存できない場合 ・・・配送料の負担の情報は1以外でないと登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

11) Item アイテムの保存 アイテムが保存できない場合 発送元の地域の情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

12) Item アイテムの保存 アイテムが保存できない場合 ・・・発送元の地域の情報は1以外でないと登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

13) Item アイテムの保存 アイテムが保存できない場合 発送までの日数の情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

14) Item アイテムの保存 アイテムが保存できない場合 ・・・発送までの日数は1以外でないと登録できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

15) Item アイテムの保存 アイテムが保存できない場合 価格の情報がないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

16) Item アイテムの保存 アイテムが保存できない場合 価格の範囲がの¥300~¥9,999,999の間でないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

17) Item アイテムの保存 アイテムが保存できない場合 価格が299円以下だと出品できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

18) Item アイテムの保存 アイテムが保存できない場合 価格が10000000円以上だと出品できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

19) Item アイテムの保存 アイテムが保存できない場合 価格は半角数字のみでないとアイテムは保存できない
Failure/Error: item.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')

NoMethodError:
undefined method `attach' for nil:NilClass
# ./spec/factories/items.rb:15:in `block (3 levels) in <main>'
# ./spec/models/item_spec.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.52755 seconds (files took 5.33 seconds to load)
19 examples, 19 failures

Failed examples:

rspec ./spec/models/item_spec.rb:10 # Item アイテムの保存 アイテムが保存できる場合 全ての情報が存在すれば登録できる
rspec ./spec/models/item_spec.rb:16 # Item アイテムの保存 アイテムが保存できない場合 ・・・imageが空では登録できない
rspec ./spec/models/item_spec.rb:21 # Item アイテムの保存 アイテムが保存できない場合 nameが空だとアイテムは保存できない
rspec ./spec/models/item_spec.rb:27 # Item アイテムの保存 アイテムが保存できない場合 商品の説明がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:33 # Item アイテムの保存 アイテムが保存できない場合 カテゴリーの情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:38 # Item アイテムの保存 アイテムが保存できない場合 ・・・カテゴリーの情報は1以外でないと登録できない
rspec ./spec/models/item_spec.rb:44 # Item アイテムの保存 アイテムが保存できない場合 商品の状態の情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:49 # Item アイテムの保存 アイテムが保存できない場合 ・・・商品の状態の情報は1以外でないと登録できない
rspec ./spec/models/item_spec.rb:55 # Item アイテムの保存 アイテムが保存できない場合 配送料の負担の情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:60 # Item アイテムの保存 アイテムが保存できない場合 ・・・配送料の負担の情報は1以外でないと登録できない
rspec ./spec/models/item_spec.rb:65 # Item アイテムの保存 アイテムが保存できない場合 発送元の地域の情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:70 # Item アイテムの保存 アイテムが保存できない場合 ・・・発送元の地域の情報は1以外でないと登録できない
rspec ./spec/models/item_spec.rb:76 # Item アイテムの保存 アイテムが保存できない場合 発送までの日数の情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:81 # Item アイテムの保存 アイテムが保存できない場合 ・・・発送までの日数は1以外でないと登録できない
rspec ./spec/models/item_spec.rb:87 # Item アイテムの保存 アイテムが保存できない場合 価格の情報がないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:92 # Item アイテムの保存 アイテムが保存できない場合 価格の範囲がの¥300~¥9,999,999の間でないとアイテムは保存できない
rspec ./spec/models/item_spec.rb:97 # Item アイテムの保存 アイテムが保存できない場合 価格が299円以下だと出品できない
rspec ./spec/models/item_spec.rb:102 # Item アイテムの保存 アイテムが保存できない場合 価格が10000000円以上だと出品できない
rspec ./spec/models/item_spec.rb:107 # Item アイテムの保存 アイテムが保存できない場合 価格は半角数字のみでないとアイテムは保存できない