この記事はプログラミング学習者がコードを書く中で得られた内容を備忘録を兼ねて記事にしたものです。間違った所などあればご指摘頂けると嬉しいです。
変数の受け渡しについて
Railsで変数を受け渡す時にcontrollerからviewへ受け渡すというのは良くやります。
これまでもコードを書く中で何度も使ってきました。
class MerchandisesController < ApplicationController
def index
@merchandises = Merchandise.with_attached_image
end
end
<div class="col mb-5">
<div class="card h-100">
<!-- Product image-->
<% if merchandise.image.attached? %>
<%= image_tag merchandise.image, :size => '269x170' %>
<% end %>
<!-- Product details-->
<div class="card-body p-4">
<div class="text-center">
<!-- Product name-->
<h5 class="fw-bolder">
<%= link_to merchandise.name, merchandise_path(merchandise) %>
</h5>
<!-- Product price-->
¥<%= merchandise.amount.to_formatted_s(:delimited) %>-
</div>
</div>
</div>
</div>
<% end %>
上記コードではcontrollerで作成した@merchandises
というインスタンス変数の値をviewファイルの中で展開してレンダリングする内容です。
学習を進めていく中でviewファイルがトリガーとなって値をcontrollerに渡す機能が必要となりました。
最初は方法をなかなか見つけられず四苦八苦しましたが、何とか見つけられて実装した機能にも取り込んだ書き方を2種類お伝えします。
form_withヘルパーを使って値を渡す場合
<%= form_with model: @cart_item, url: create_path(@merchandise), method: :get, local: true do |f| %>
<div class="form-group">
<%= f.label :quantity, CartItem.human_attribute_name(:quantity) %>
<%= f.text_field :quantity, class: 'form-control' %>
</div>
<%= f.submit 'Add to cart', class: "btn btn-outline-dark mt-auto" %>
<% end %>
通常、form_withヘルパーではブラウザで入力された値を受け取ってcontrollerへ渡します。
<%= f.text_field :quantity, class: 'form-control' %>
が入力欄のコードでsubmitボタンが押されるとquantity
変数の中に入力された値が入ってcontrollerへ伝わります。
私の場合、この時取得が必要な値はquantity
と表示されているページデータのid
でした。
quantity
は上述の通りsubumitボタンを押せば取得できます。
問題はもう一つのid
です。
form_withヘルパーはurl
を指定することでsubmitボタンを押した際に指定のアクションへ飛ぶことができます。
<%= form_with model: @cart_item, url: create_path(@merchandise), method: :get, local: true do |f| %>
この時、pathの後ろに括弧書きで変数を書くことでcontorollerに値を渡すことができるということが分かりました。
pry-byebugとbinding.pryを使ってparamsの中身を確認した所、format
としてid
を含んでいることが分かりました。
後はcontroller側でformatの値を受け取るだけです。
@merchandise = Merchandise.find_by(id: params[:format])
if params[:quantity].to_i <= 0 || params[:quantity].blank? # quantityを使うif文
これで無事view側からcontrollerへ必要な値を受け渡すことができるようになりました。
link_toメソッドを使って値を渡す場合
link_toメソッドは通常表示されたボタンを押した際に指定されたpathへ移動する性能です。
<%= link_to 'Add to cart', create_path, class: "btn btn-outline-dark mt-auto" %>
上のサンプルですとcreate_path
がそれに当たります。
ここでもform_withヘルパーと同様にcontrollerに対して2つの値を引き渡す必要があります。
quantity
とid
です。
しかも今回はquantity
は1
という固定の定数を渡したいという状況でした。
link_toメソッドもfrom_withと同様にurlを書く時に値を渡すことができます。
但し、form_withヘルパーの場合はformで入力された値一つとurlからの値一つという方法でした。
幸いlink_toメソッドからは値を二つ渡せることが調べて分かりました。
<% @merchandises.each do |merchandise| %>
<%= link_to 'Add to cart', create_path(merchandise.id, quantity:1), class: "btn btn-outline-dark mt-auto" %>
調査をもとに修正したコードは上記になります。
create_pathの後ろに括弧書きで値を二つ記述することで値を渡せるようになりました。
以上、viewからcontrollerに値を渡す方法をご紹介しました。
日頃、Qiitaを含めた記事には助けられているので、少しでもお役に立てると嬉しいです。