LoginSignup
29
23

More than 3 years have passed since last update.

Couldn't find Item with 'id'= を解決する

Posted at

エラー内容

フリマアプリ作成において、購入機能を実装中に起こったエラー
購入までの流れは、
1.商品一覧ページ
2.商品詳細ページ
--- ここでエラー ----
3.購入確認ページ
4.(購入完了)
スクリーンショット 2020-04-13 9.06.15.png

Couldn't find Item with 'id'=なので、「itemモデルのidが見つからない」とういエラーなます

エラー原因

コントローラー

まずエラーが出ているitmescontrollerについて
今回購入確認ページへのアクションはpurchase、購入のアクションはbuyとし、itmescontrollerに記述しています。purchase,buyアクションについてもitemのidを見つけるようにbefor_actionで設定していますので、コントローラーは問題なさそうです。

items_controller.rb
before_action :set_item, only: [:edit, :update, :destroy, :purchase, :buy]
#------省略--------
def purchase
    card = Card.where(user_id: current_user.id).first
end

def buy
    card = Card.where(user_id: current_user.id).first
    Payjp.api_key = Rails.application.secrets.payjp_private_key
    Payjp::Charge.create(
    :amount => @item.price,
    :customer => card.customer_id,
    :currency => 'jpy',
    )
    redirect_to root_path
 end

def set_item
    @item = Item.find(params[:id])
  end

  def item_params
    params.permit(
      :name,
      :item_condition_id,
      :introduction,
      :price,
      :prefecture_code,
      :trading_status,
      :postage_payer_id,
      :size_id,
      :preparation_day_id,
      :postage_type_id,
      :category_id,
      item_imgs_attributes: [:src, :_destroy, :id]
      ).merge(seller_id: current_user.id, trading_status: 0)
  end

ルーティング

次にpurchaseアクションを実行するためのルーティングをターミナルで確認します。
★★このルーティングの設定がエラーの原因でした。
purchaseアクションのURI Patternにidが入っていません。
ルーティングでidが入っていないのに、コントローラーでidの設定をしてるため、そりゃもちろんエラーになります。

($rails routes)
 purchase_items  GET      /items/purchase(.:format)        items#purchase
 buy_items     POST     /items/buy(.:format)             items#buy

ではルーティングの記述内容を確認し、修正します。

routes.rb
#ーーーーーーーー 修正前 ーーーーーーーーーー
resources :items do
    collection do
      get 'get_category_children', defaults: { format: 'json' }
      get 'get_category_grandchildren', defaults: { format: 'json' }
      get 'purchase', to: 'items#purchase'
      post 'buy', to: 'items#buy'
    end
  end
#ーーーーーーーー 修正後 ーーーーーーーーーー
resources :items do
    collection do
      get 'get_category_children', defaults: { format: 'json' }
      get 'get_category_grandchildren', defaults: { format: 'json' }
    end
    member do
      get 'purchase', to: 'items#purchase'
      post 'buy', to: 'items#buy'
    end
  end

上記の通り、resources :items doでネストしている'purchase',buyアクションのルーティングがcollection domember doへと変更しています。
今回のようにidが必要な時はmember、必要無い時はcollectionを使います。

修正後再度ターミナルで確認します

($rails routes)
 purchase_items  GET      /items/:id/purchase(.:format)        items#purchase
 buy_items     POST     /items/:id/buy(.:format)             items#buy

ビュー

ルーティング変更に伴い、ページ移動のためのパスを変更して完了!!
(@item.id)を忘れないよう注意しましょう。

item-detail.html.hanl

(修正前)
.item-price__purchase-button
  = link_to "購入画面に進む", purchase_items_path
(修正後)
.item-price__purchase-button
  = link_to "購入画面に進む", purchase_item_path(@item.id)

参考記事

エラー解決までに参考にした記事、または関連する箇所で勉強になった記事です。
Railsのルーティングの種類と要点まとめ
Ruby on Rails のエラーCouldn't find with id=が表示された際の3つの確認点

29
23
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
23