Rails: 覚書: 別画面からモデルの一部の項目だけを編集する
外観
目的
別画面からモデルの一部の項目だけを編集したい。
下記の要領でサンプルアプリを作成する。
管理者はモデルの全ての項目を編集できる。
会員は一部の項目だけを編集できる。
同じモデルを編集するのでフォームオブジェクトは不必要。
会員当人(Owner)をサブリソースとして、Rails: 覚書: DHH流のルーティングで実装する。また、ルーティングの命名と管理者権限が必要かどうかについては別の関心事として扱いadminを付けるようなことはしていない。
2021/03/05 追記
ルーティングを別ファイルに分ける場合は別のルーティングが良い気がしました。
環境
Ruby 2.7.2
Rails 6.1.3
画面
足場の準備
メーラーなどを使用しない設定でアプリを準備する。
rails new try_another_view -MCJT
cd try_another_view && tmux
bin/rails g scaffold Member \
name agreed:boolean \
admin_note:text admin_confirmed:boolean
bin/rails db:migrate
バリデーションを追加する。
app/models/member.rb
class Member < ApplicationRecord
validates :name, presence: true, length: { maximum: 100 }
end
会員による編集
会員は赤枠の項目だけを更新できる。
ルーティングを加筆修正する。
config/routes.rb
Rails.application.routes.draw do
resources :members do
resource :owners, only: %i[edit update], module: 'members'
end
end
#bin/rails routes -c Members::OwnersController
bin/rails routes -c owners
Prefix Verb URI Pattern Controller#Action
edit_member_owners GET /members/:member_id/owners/edit(.:format) members/owners#edit
member_owners PATCH /members/:member_id/owners(.:format) members/owners#update
PUT /members/:member_id/owners(.:format) members/owners#update
一覧に会員編集用のリンクを追加する。
app/views/members/index.html.erb
<th colspan="4"></th>
...
<td><%= link_to 'Edit2', edit_member_owners_path(member) %></td>
コントローラーを生成する。
bin/rails g controller 'members/owners' \
edit \
--skip-routes --no-helper --no-assets
MembersControllerを参考に実装する。
app/controllers/members/owners_controller.rb
class Members::OwnersController < ApplicationController
before_action :set_member, only: %i[edit update]
def edit
end
def update
if @member.update(member_params)
redirect_to @member, notice: 'Member was successfully updated.'
else
render :edit, status: :unprocessable_entity
end
end
private
def set_member
@member = Member.find(params[:member_id])
end
def member_params
params.require(:member).permit(:name, :agreed)
end
end
Membersのedit/_formビューを参考に実装する。
editのみで使用するので部分テンプレートは使用しない。
ローカル変数memberをインスタンス変数@memberに置き換える。
editビューのBackリンクを流用する。
app/views/members/owners/edit.html.erb
<h1>Editing Member</h1>
<%= form_with(model: @member, url: member_owners_url) do |form| %>
<% if @member.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@member.errors.count, "error") %> prohibited this @member from being saved:</h2>
<ul>
<% @member.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :agreed %>
<%= form.check_box :agreed %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
<%= link_to 'Back', members_path %>
以上です。
この記事が気に入ったらサポートをしてみませんか?