LoginSignup
maasiii
@maasiii

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

モーダルの変数取得に悩んでいます。

解決したいこと

更新したスキル名を取得し、モーダル内で表示させたい。

アプリの仕様
ruby on rails でポートフォリオサイトのようなものを作っています。
解決したいページの内容は、スキルを表示する表があり、スキルのレベルだけ編集可能にしており、セレクターで数値を選択し、保存ボタンを押す。保存ボタンが押されると、モーダルがオープンし、{スキル名}のレベルを保存しました!と表示される。
{}内に更新したスキル名が入るというような感じです。

発生している問題・エラー

<%= @skill.name %>を取得できず、else処理になってしまう。

該当するソースコード

views/shared/_update_modal.html.erb
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" data-backdrop="static">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-body text-center mt-5">
        <% if @skill.present? %>
          <p><%= @skill.name %></p>
        <% else %>
          <p>スキルが更新されていません</p>
        <% end %>
        <button type="button" class="btn btn-primary us-btn" data-dismiss="modal">スキル編集ページに戻る</button>
      </div>
    </div>
  </div>
</div>

skills_controller.rb
def update
    @skill = Skill.find(params[:id])
    respond_to do |format|
      if @skill.update(skill_params)
        @updated_skill = true
        format.turbo_stream do
          render turbo_stream: turbo_stream.append(
            :modal,
            partial: 'shared/update_modal',
          )
        end
        format.json { render json: { success: true } }
      else
        format.html { render 'edit', status: :unprocessable_entity }
        format.json { render json: { success: false, errors: @skill.errors.full_messages } }
      end
    end
  end

自分で試したこと

元々は、turboのことなどよくわからず、javascriptやindexページのcontroller経由して変数渡したりなど色々やっていましたが、turboを使用すれば、modalをパーシャルで準備して表示できる感じだったので、上記のようにしました。デバッグし、updateメソッドのどこかで止まっているのかと思いましたが、正常に動いており、レベルの更新も問題なくできています。
@skillにデータが格納されていることも確認できたので、何が問題なのかわからなくなりました。
index.html.erbはviews/positions/配下にあります。
positions_controllerに変数受け取りのアクションが必要なのでしょうか?


    51: def update
    52:   @skill = Skill.find(params[:id])
    53:   respond_to do |format|
    54:     if @skill.update(skill_params)
    55:       @updated_skill = true
    56:       format.turbo_stream do
    57:         render turbo_stream: turbo_stream.append(
    58:           :modal,
    59:           partial: 'shared/update_modal',
    60:         )
    61:       end
    62:
 => 63:       binding.pry
    64:
    65:       format.json { render json: { success: true } }
    66:     else
    67:       format.html { render 'edit', status: :unprocessable_entity }
    68:       format.json { render json: { success: false, errors: @skill.errors.full_messages } }
    69:     end
    70:   end
    71: end

[1] pry(#<SkillsController>)> @skill
=> #<Skill:0x0000ffff8d7928a8
 id: 35,
 position_id: 1,
 name: "Go",
 level: 70,
 created_at: Mon, 15 May 2023 03:49:21.807342000 UTC +00:00,
 updated_at: Thu, 18 May 2023 03:06:30.811758000 UTC +00:00>
[2] pry(#<SkillsController>)> @skill.name
=> "Go"

ご教授いただけますと幸いです🙇

0

3Answer

partialに対して変数を渡せていないのが、原因だと思います。

  format.turbo_stream do
    render turbo_stream: turbo_stream.append(
      :modal,
      partial: 'shared/update_modal',
    )
end

↑ ここの部分で変数を渡すと良さそうです!

1

Comments

  1. @maasiii

    Questioner

    @apierce さん
    今回も、アドバイスありがとうございます!
    公式を見るところ、turbo updateなどを使用する際は、
    HTMLを<turbo streame>でラップしなければ使用できないということでしょうか?
    自分の読解力が足りないため、質問させていただきました。

    positions/index.html.erb
    <div class="container mt-5">
      <div class="card">
        <div class="card-body">
          <div class="d-flex justify-content-between mt-3">
            <div>
              <h3>バックエンド</h3>
              <div class="border-underbar-1"></div>
            </div>
            <%= link_to "スキルを追加する", new_skill_path(position: "backend"), class: "btn btn-primary us-btn" %>
          </div>
          <div class="table-container">
            <table class="p-table mt-4">
              <thead class="p-thead">
                <tr class="p-tr">
                  <th class="skill-header" style="padding-left: 3%">習得スキル</th>
                  <th>習得レベル</th>
                </tr>
              </thead>
              <tbody>
                <% @backend_skills.each do |skill| %>
                <tr class="p-tr">
                  <td class="p-td">
                    <span class="skill-name"><%= skill.name %></span>
                  </td>
                  <%= form_with(model: skill, url: skill_path(skill), method: :patch, local: true, id: "edit-skill-form-#{skill.id}") do |f| %>
    
                  <td class="p-td">
                    <%= f.select :level, options_for_select((0..100).step(10), skill.level), include_blank: true %>
                  </td>
                  <td class="p-td">
                    <%= f.submit "習得レベルを保存する", class: "btn skill-edit-btn" %>
                  </td>
                  <% end %>
                  <td class="p-td">
                    <%= link_to "スキルを削除する", skill_path(skill), data: { "turbo-method": :delete, toggle: "modal", target: "#deleteModal" }, remote: true, class: "btn skill-delete-btn" %>
                  </td>
                </tr>
                <% end %>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
    

    上記のf.select :levelのスキルレベルを非同期で更新できるようにしたいと思っています。

    お時間ある際に助言いただけますと幸いです🙇

  2. @maasiii

    すみません、多分僕が添付したリンクが良くなかったです。
    部分テンプレート側で変数を参照するには、その変数を渡してあげる必要があります。

    skills_controller.rb
      format.turbo_stream do
        render turbo_stream: turbo_stream.append(
          :modal,
          partial: 'shared/update_modal',
          locals: { skill: @skill } # ここを追加
        )
      end
    

    ↑のようにすることで、views/shared/_update_modal.html.erbskillを参照できるようになります。

  3. @maasiii

    Questioner

    @apierce
    ありがとうございます!!
    ちなみになのですが、rails7の非同期処理はturboで実装するのが普通なのでしょうか?
    以前読んだ記事で、7からはjqueryが非推奨というのをみたのでajaxは使用あまりしないのか、、?
    しかし、今回自分が実装したかったのがindexページで非同期で値の更新をし、更新できた時にmodalが発火し、モーダルで更新したスキル名を取得する。など、少し複雑なように感じ、turboだけでできるのか?(turboは簡単だが柔軟性はあまりないなどを記事で見かけた。。)などと困惑していました。

    お忙しいかと思いますので、お時間ある際に助言いただけますと幸いです。🙇‍♂️💦

This answer has been deleted for violation of our Terms of Service.
This answer has been deleted for violation of our Terms of Service.

Your answer might help someone💌