ネストリソース

作成しているRailsアプリにおいて、親子関係をもつモデルがあり、ルーティングで親子関係を表現したい場合などは あるリソースの配下に子リソースを置けばいい(ネストリソース)。

class Theme < ApplicationRecord
 has_many :categories
end

class Category < ApplicationRecord
  belongs_to :theme
end
resources :themes do
  resources :categories 
end

ネストリソースを使う事により、ThemesControllerにルーティングできるようになる。 その際にルーティングヘルパーも作成される。

theme_categories_url
edit_theme_category_path

など。

その際に、最初のパラメータとしてThemeモデルのインスタンスを1つ取ります (theme_categories_url(@theme))。 またネストリソースのネスティングは一回までにしておくのが無難。

ネストリソースをより、シンプルに記述する方法の一つに「:shallowオプション」がある。

コレクション(:idを持たないアクション)のみを親スコープで定義する。 メンバー(:idを持つアクション)はネストに含めない。

resources :themes do
  resources :categories, only: [:index, :new, :create]
end
resources :categories, only: [:show, :edit, :update, :destroy]

これを:shallowオプションを使うと

resources :themes do
  resources :categories, shallow: true
end

また親リソースで:shallowオプションを指定すると、すべてのネストしたリソースが浅くなる。

resources :themes, shallow: true do
  resources :categories
  resources :comments
  resources :likes
end

下記も上記と同じ。

shallow do 
resources :themes
  resources :categories
  resources :comments
  resources :likes
end

また浅いルーティングカスタムする二つのscopeメソッドが存在する。

①:shallow_pathオプション →指定されたパラメータをメンバーのパスの冒頭にだけ追加する。 (例: standard/categories/:id(.:format))

scope shallow_path: "standard" do
  resources :themes do
    resources :categories, shallow: true
  end
end

②:shallow_prefixオプション →指定されたパラメータを (パスではなく) メンバーの名前付きヘルパー名の冒頭に追加する。 (例: standard_categories_path)

scope shallow_prefix: "standard" do
  resources :themes do
    resources :categories, shallow: true
  end
end

🐤

参照 :Rails guide