👻
[Rails]resource・resourcesの違い
今回のエラーについて
Rails.application.routes.draw do
devise_for :users
root to: "homes#top"
get "/homes/about" => "homes#about", as: "about"
resources :post_images, only: [:new, :create, :index, :show, :destroy] do
# 下記が間違い
resources :favorites, only: [:create, :destroy]
resources :post_comments, only: [:create, :destroy]
end
resources :users, only: [:show, :edit, :update]
end
ルーティングで上記書き方をしたらエラーが出ました。
# 複数形が間違い
resources :favorites, only: [:create, :destroy]
# 正しくは単数形
resource :favorite, only: [:create, :destroy]
「resources :favorites」と複数形で書いてしまったことにより、
複数形でいいねをしようとすると、「Routing Error」が出て、URLが"/tasks/3/favorites/3"になってしまう。
resource
と resources
で、生成される URL とルーティングが異なる。
resources(複数形・間違い)
resources
は、リソースが複数のインスタンスを持つ場合に使う。
つまり、データベースに保存される 複数のインスタンス(レコード) を管理するために使われる。
ルーティング例:
resources :favorites, only: [:create, :destroy]
生成される URL:
POST /favorites → favorites#create(「いいね」作成)
DELETE /favorites/:id → favorites#destroy(「いいね」削除)
- POST /favorites のリクエストで、新しい「いいね」を作成できる。
- DELETE /favorites/:id では、どの「いいね」を削除するのか id が必要になる。
- これは「1つの投稿に対して、複数のユーザーがいいねをつける」場合に適している。
resources
は、リソースが複数存在するケースを対象としているため、/favorites/:id
のように :id
が URL に含まれる。
resources
を使う場合のデータモデル
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :post_image
end
favorites
テーブルには、以下のようなデータが入る:
id | user_id | post_image_id |
---|---|---|
1 | 2 | 5 |
2 | 3 | 5 |
3 | 2 | 6 |
→ つまり、1つの投稿 (post_image_id: 5
) に対して、複数のユーザー (user_id: 2, 3
) が「いいね」をつけられる。
resource(単数形・正しい)
resource
は、今回のような「リソースが 1つだけ しか存在しない」ことが前提。
つまり、「特定のユーザーが1つの投稿に対して、1回だけ いいねをつける」場合に適している。
ルーティング例:
resource :favorite, only: [:create, :destroy]
生成される URL:
POST /favorite → favorites#create(「いいね」作成)
DELETE /favorite → favorites#destroy(「いいね」削除)
- URL に :id が含まれない(/favorite/:id ではなく /favorite)。
- これは「1つの投稿に対して、1人のユーザーが1回だけ いいねをつける」場合に適している。
- 例えば、Twitter の「いいね」のように、ユーザーが同じ投稿に2回いいねできない設計。
resource
を使う場合のデータモデル
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :post_image
validates :user_id, uniqueness: { scope: :post_image_id }
end
favorites
テーブルのデータは、同じユーザーが同じ投稿に2回以上「いいね」できないようにする。
id | user_id | post_image_id |
---|---|---|
1 | 2 | 5 |
2 | 3 | 6 |
→ つまり、各ユーザー (user_id
) は、各投稿 (post_image_id
) に 1回だけ いいねできる。
Discussion