📘 hkob-astro-notion-blog

これまではてなブログにて情報発信をしていましたが、令和5年3月22日より、こちらでの情報発信を始めました。2019年以前の古い記事は過去の Middleman 時代のものなので、情報が古いです。記録のためだけに残しています。

gakuseis コントローラの作成(3) - 不定期刊 Rails App を作る(26)

💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。

edit の form_with を書いていたが,kurasu_id を別に渡すには url を書く必要がある. これだとあまり Rails っぽくなくなるので,関連付けを使った controller に変更することにした. これまでは gakuseis_controller で記載していたが,kurasus/gakuseis_controller に変更した. このため,

のページの内容も修正した.

gakusei_spec の記述(edit と update)

spec/requests/kurasus/gakusei_spec.rb を修正する.

describe 'GET #edit' do
  context 'owned object' do
    subject { -> { get edit_kurasu_gakusei_path(kurasu, object) } }
    it_behaves_like :response_status_check, 200
    it_behaves_like :response_body_includes, 'foo'
  end

  context 'not owned kurasu' do
    let(:return_path) { kurasus_path }
    subject { -> { get edit_kurasu_gakusei_path(not_mine.kurasu, not_mine) } }
    it_behaves_like :response_status_check, 302
    it_behaves_like :redirect_to
    it_behaves_like :flash_alert_message, '学生を編集する権限がありません.'
  end

  context 'not owned object' do
    subject { -> { get edit_kurasu_gakusei_path(kurasu, not_mine) } }
    it_behaves_like :response_status_check, 302
    it_behaves_like :redirect_to
    it_behaves_like :flash_alert_message, '学生を編集する権限がありません.'
  end
end

gakusei_controller の記述(edit と update)

app/controllers/kurasus/gakuseis_controller.rb を記述する.

def edit
  redirect_to kurasus_path, alert: alert_message(Gakusei) and return if @kurasu.nil?
  redirect_to(kurasu_gakuseis_path(kurasu_id: @kurasu.id, edit_mode: true), alert: alert_message(Gakusei)) and return if @gakusei.nil?
end

def update
  redirect_to(kurasu_gakuseis_path(@kurasu, edit_mode: true), alert: alert_message(Gakusei)) and return if @gakusei.nil?
  if @gakusei.update_attributes(gakusei_params)
    redirect_to kurasu_gakuseis_path(@kurasu, edit_mode: true), notice: notice_message(Gakusei)
  else
    flash.now[:alert] = alert_message(Gakusei)
    render action: :edit
  end
end
edit の view を作成
  1. app/views/kurasus/gakuseis/edit.html.haml を記述する.kurasus/edit と同様に _form の呼び出しのみである.
    - content_for :title do
      - @title = "#{t '.title'}: #{@gakusei.name}"
    = render partial: 'form', locals: {gakusei: @gakusei, kurasu: @kurasu}
  2. app/views/kurasus/gakuseis/_form.html.haml を記述する.model の部分を [@kurasu, gakusei] とすることで,階層的な route になる.
    = form_with model: [@kurasu, gakusei], local: true do |f|
      %table
        %tr
          %th= f.label :number
          %td= f.text_field :number
        %tr
          %th= f.label :name
          %td= f.text_field :name, autofocus: true
        %tr
          %td{colspan: 2}
            = f.submit
guard の結果

guard の結果は以下のようになった

GET #edit
  owned object
    behaves like response_status_check
      response should be 200
    behaves like response_body_includes
      response body includes foo
  not owned kurasu
    behaves like response_status_check
      response should be 302
    behaves like redirect_to
      should redirect to "/kurasus"
    behaves like flash_alert_message
      should eq "学生を編集する権限がありません."
  not owned object
    behaves like response_status_check
      response should be 302
    behaves like redirect_to
      should redirect to "/kurasus/3201/gakuseis?edit_mode=true"
    behaves like flash_alert_message
      should eq "学生を編集する権限がありません."
PATCH #update
  owned object
    正しいパラメータに対して
      behaves like response_status_check
        response should be 302
      behaves like change_object_value_by_update
        should change `klass.find(object.id).send(key)` from "foo" to "new name"
      behaves like redirect_to
        should redirect to "/kurasus/3207/gakuseis?edit_mode=true"
      behaves like flash_notice_message
        should eq "学生を更新しました."
    不正なパラメータに対して
      behaves like response_status_check
        response should be 200
      behaves like not_change_object_value_by_update
        should not change `klass.find(object.id).send(key)`
      behaves like flash_alert_message
        should eq "学生が更新できません."
  not owned object
    behaves like response_status_check
      response should be 302
    behaves like redirect_to
      should redirect to "/kurasus/3214/gakuseis?edit_mode=true"
    behaves like flash_alert_message
      should eq "学生が更新できません."

長くなったので今日はここまで