

初めまして、ruby,ruby on rails, JavaScript初学者です。

掲題の件飲食店の予約サイトを作成しているのですが、active
hashを使用し、選択されたコース料理によって一人当たりの費用が出るように実装を行いたいです。

試したこと  
active hashを用いたモデル内に:nameと:priceを作成した。  
→プルダウン表示は可能ですが、連動させることができませんでした。

gyazoの画像も添付させていただきます。  
<https://gyazo.com/5fa62942e8e1a135e738535a51bcb9de>

不足情報等がございましたら、ご質問いただけると幸いです。  
どうぞ宜しくお願い致します。

* * *

models/menu.rb

[code]

    class Menu < ActiveHash::Base
      self.data = [
      { id: 1, name: '季節のおまかせコース', price: '8,800'},
      { id: 2, name: '海鮮鍋セットコース', price: '10,800'},
      { id: 3, name: '季節のおまかせコース + 2時間飲み放題', price: '12,800'},
      { id: 4, name: '海鮮鍋セットコース + 2時間飲み放題', price: '15,000'}
      ]
    
      include ActiveHash::Associations
      has_many :reservations
    end
    
[/code]

views/reservation.html.erb

[code]

    <h1><%= link_to '予約フォーム', root_path, class:'reservation-form'%></h1>
    <%= form_with model: @reservation, url: new_reservation_path, method: :get, class: 'reservation', local: true do |f| %>
    
        <div class="reservation-price">
          <h2>コース選択</h2>
    
          <div calss="reservation-date">
            <%= f.label :日付を選択, class: 'label'%><br />
            <%= f.date_field :date, class: 'date' %>
          </div>
    
          <div class="reservation-time">
            <%= f.label :時間を選択, class: 'label' %><br />
            <%= f.time_field :time, class: 'time'%>
          </div>
    
          <div class="reservation-people">
            <%= f.label :人数%><br />
            <%= f.number_field :people, class: 'people'%>人
          </div>
    
          <%# 該当箇所 %>
          <div class="menu">
            コース<br />
            <%= f.collection_select(:menu_id, Menu.all, :id, :name, {})%>
          </div>
          
          <div class="person-price">
            <span>1人当たりのお支払い</span><br />
            <span>
            <span></span>円 
            </span>
          </div>
          <%# /該当箇所 %>
    
          <div class="total-price">
            <span>合計金額</span><br />
            <span>
            <span></span>円
            </span>
          </div>
    
          <div class="reservation-remark">
            <%= f.label :その他%><br />
            <%= f.text_area :remark, placeholder:"嫌いな食べ物など",class: 'remark'%>
          </div>
    
        <div>
          <%= f.submit "予約する"%> <br />
        </div>
    
      <div class="reservation-btn">
        <%= link_to '戻る', root_path, class:'reservation-form'%> 
      </div>
      
    <% end %> 
    
[/code]


CC BY-SA 4.0
2021-08-20T06:12:52.457
80932
2021-08-21T10:31:39.383
2021-08-20T07:31:26.017
3060
47748
question
ruby-on-rails ruby
active hashを使用し、選択された商品によって金額の表示を行いたい


予約ボタンを押す前にプルダウンを変更した際に金額を表示するってことでいいんですよね？

プルダウンから予約内容を変更しただけではサーバーへの通信は発生せず  
サーバーサイドだけでもってるデータは利用できません

予約する submit をクリックしてはじめてサーバーへの通信が起きて  
ページ遷移によってサーバーサイドデータを利用することができます

* * *

実現方法は大きく以下２つあります

プルダウンを変更するたびにページ遷移を起こして  
サーバーサイドで金額を埋めたページを生成する

クライアントサイドでプルダウン変更時に金額部分のHTMLを動的に変更する

* * *

後者の方法が自然だと思うんですが price をクライアントと共有するために  
option tag にうめこむなり javascript 内でテーブルをもつ必要があります

たとえば collection_select じゃなく  
f.select で以下のように option タグに price を埋め込みます

[code]

    <%= f.select :menu_id, (Menu.all.map {|m| [m.name, m.id, {'data-price' => m.price }]}), {}, {id: 'menu_select'} %>
    
[/code]

これで以下のようなHTMLが生成されます

[code]

    <select id="menu_select">
    <option value="1" data-price="8800">季節のおまかせコース</option>
    <option value="2" data-price="10800">海鮮鍋セットコース</option>
    <option value="3" data-price="12800">季節のおまかせコース + 2時間飲み放題</option>
    <option value="4" data-price="15000">海鮮鍋セットコース + 2時間飲み放題</option>
    </select>
    
[/code]

JS側はたとえばこんな感じ

[code]

    // プルダウンを変更するたびにこの処理が呼ばれる
    $('#menu_select').on('change', () => {
      
      // 選択されたオプションに埋め込まれた price を取得
      const price = $('#menu_select > option:selected').data('price');
      
      // total_price のIDのついた span の中に金額文字列をセットする
      $('#total_price').text(price);
    })
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <select id="menu_select">
    <option value="1" data-price="8800">季節のおまかせコース</option>
    <option value="2" data-price="10800">海鮮鍋セットコース</option>
    <option value="3" data-price="12800">季節のおまかせコース + 2時間飲み放題</option>
    <option value="4" data-price="15000">海鮮鍋セットコース + 2時間飲み放題</option>
    </select>
    
    <div class="total-price">
      <span>合計金額</span><br />
      <span id="total_price"></span>円
      </span>
    </div>
[/code]

* * *

pure javascript 版です

[code]

    const menu_select = document.getElementById("menu_select")
    menu_select.addEventListener('change', (event) => {
      const selected_index = menu_select.selectedIndex;
        const selected_option = menu_select.options[selected_index];
      const price = selected_option.getAttribute("data-price");
      document.getElementById("total_price").innerHTML = price;
    });
[/code]

[code]

     <select id="menu_select">
        <option value="1" data-price="8800">季節のおまかせコース</option>
        <option value="2" data-price="10800">海鮮鍋セットコース</option>
        <option value="3" data-price="12800">季節のおまかせコース + 2時間飲み放題</option>
        <option value="4" data-price="15000">海鮮鍋セットコース + 2時間飲み放題</option>
        </select>
    
        <div class="total-price">
          <span>合計金額</span><br />
          <span id="total_price"></span>円
          </span>
        </div>
[/code]


CC BY-SA 4.0
2021-08-20T09:22:50.377
80934
2021-08-21T10:31:39.383
2021-08-21T10:31:39.383
80932
answer