1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsでワクワク個人開発  第4回: ネストされたリソースでCRUD処理

Posted at

ルーティングの設定

 わからない言葉が増えてきた。リソースというのは操作可能(作成・削除・更新・編集)なデータ群のことであり、ネストとは親子構造のことだった。私はUserとPlantをネストで扱いたかった。URLで考えると以下のようなイメージだ。

/users/(ユーザーid) /plants/ (ユーザーが所持しているplantのid)

 これを実現するには第3回で書いたように、モデルに対して関連付けをする必要がある。また、ルーティングに対してもいろいろやらなくてはいけない。

config/routes.rb

Rails.application.routes.draw do
  root to: 'users#index'
  devise_for :users
  resources :users do
    resources :plants
  end
end

 root to: 'users#index' とはトップページの設定、 devise_for :users はログイン機能に関するものだ。ここでは詳しく述べない。resources... が大事だ。このように入れ子構造にすることでネストされたリソースが実現できる。

記述が終わったらターミナルで rails routesを打ち込んで、どのようなルーティングがなされているか確認して欲しい。

Userのコントローラーの追記とViewの作成

 次はUserのコントローラーに追記をする。すでに以前の記事ですでにコントローラーはつくられているはずだ。以下のようにする。

app/controllers/users_controller.rb

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end
end

 ここではindexアクションとshowアクションのみ作る。

次にviewファイルをつくろう。index.html.erbとshow.html.erbだ。

app/views/users/index.html.erb

<h1>ユーザー一覧</h1>
<% @users.each do |user| %>
<p> アドレス <%= link_to user.email, user %></p>
<% end %>

app/views/users/show.html.erb

<h3>メールアドレス</h3>
<%= @user.email %><br>
<h3> 所有している植物 </h3>
<% @user.plants.each do |p| %>
  <li><%= p.plant_name %></li>
<% end %>

<%= link_to user.email, user %> によってindex.html.erbから ユーザーごとの詳細ページへ移動するリンクが貼られる。詳細ページでは p.plant_name によってユーザーが所有しているplantの名前が表示される。

Plantコントローラの追記とViewの作成

 今度はPlantコントローラーも書いていこう。index,newアクションなどを一気に書きくだす。(このあたりも後々解説していきたい)

class PlantsController < ApplicationController
  def index
    @user = User.find(params[:user_id])
    @plants = @user.plants
  end
  
  def new
    @user = User.find(params[:user_id])
    @plant = Plant.new
  end

  def create
    @plant = Plant.new(plant_params)
    current_user.plants.create(plant_params)    
  end

  def show
    @user = User.find(params[:user_id])
    @plant = @user.plants.find(params[:id])
  end

  private
  def plant_params
    params.require(:plant).permit(:user_id, :plant_name, :img)
  end

end

Viewファイルだが、今のところ使っているのはplants/create.html.erb ,plants/show.html.erb , plants/new.html.erbだけだ。 plants/index.html.erbは存在はしているが、通常のリンクではたどれない。

User一覧 > User詳細 > Plants詳細

という順序で閲覧するためだ。

plants/create.html.erb

<h1>登録完了</h1>
<%= link_to 'マイページへ', user_path(current_user.id) %>

plants/show.html.erb

<h1>植物 詳細</h1>
<h3>植物の名前</h3>
<%= @plant.plant_name %><br>
<h3> 植物の写真 </h3>
<%= @plant.img %><br>

plants/new.html.erb

<h1>植物-新規登録</h1>
<%= form_with model: [@user, @plant], local: true do |f| %>
  <p>植物名:<%= f.text_field :plant_name %></p>
  <%= f.submit "登録" %>
<% end %>

ネストされているリンク先の指定

 自分が一番悩んだのがこれだ。以下の三つ。

  • User詳細ページからPlant詳細ページへのリンク
  • User詳細ページからPlantの新規登録ページへのリンク
  • Plant新規登録ページからcreateアクション実行へのリンク

 順に紹介する。

User詳細ページからPlant詳細ページへのリンク

<!-- 略 -->
<% @user.plants.each do |p| %>
  <li><%= link_to p.plant_name ,[@user,p]%></li>
<% end %>
<!-- 略 -->

このようにlink_toのリンク先を配列にしてやることでネストされたページへリンクを貼ることができる。

以下のページが参考になった。

Railsのルーティング

User詳細ページからPlantの新規登録ページへのリンク

<!-- 略 -->
 <%= link_to '植物登録' ,new_user_plant_path(current_user.id) %>
<!-- 略 -->

current_user.idを利用することで、現在ログインしているUserのidを参照できる。これでリンクが貼れる。

Plant新規登録ページからcreateアクション実行へのリンク

<%= form_with model: [@user, @plant], local: true do |f| %>
  <p>植物名:<%= f.text_field :plant_name %></p>
  <%= f.submit "登録" %>
<% end %>

このform_with記法のリンク先もさきのlink_toと似ている。 今回の場合は [@user, @plant]とすることでネストされたリンクについてcreateアクションを行うことができる。
(この表現の仕方があっているのか…?)

おわりに

 現状のことがらはひとまず書き終えることができた。まだ、他人のIDのCRUD処理ができてしまうなど、問題は多い。間違いを質しながら個人開発をすすめていこう。

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?