2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails viewからcontrollerに値を渡す方法

Last updated at Posted at 2024-06-02

この記事はプログラミング学習者がコードを書く中で得られた内容を備忘録を兼ねて記事にしたものです。間違った所などあればご指摘頂けると嬉しいです。

変数の受け渡しについて

Railsで変数を受け渡す時にcontrollerからviewへ受け渡すというのは良くやります。
これまでもコードを書く中で何度も使ってきました。

merchandises_controller.rb
class MerchandisesController < ApplicationController
  def index
    @merchandises = Merchandise.with_attached_image
  end
end
index.html.erb<% @merchandises.each do |merchandise| %>
  <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ヘルパーを使って値を渡す場合

show.html.erb
<%= 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ボタンを押した際に指定のアクションへ飛ぶことができます。

show.html.erbの抜粋
<%= form_with model: @cart_item, url: create_path(@merchandise), method: :get, local: true do |f| %>

この時、pathの後ろに括弧書きで変数を書くことでcontorollerに値を渡すことができるということが分かりました。
pry-byebugとbinding.pryを使ってparamsの中身を確認した所、formatとしてidを含んでいることが分かりました。
params.png

後はcontroller側でformatの値を受け取るだけです。

carts_controller.rb
@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へ移動する性能です。

index.html.erbの抜粋
<%= link_to 'Add to cart', create_path, class: "btn btn-outline-dark mt-auto" %>

上のサンプルですとcreate_pathがそれに当たります。
ここでもform_withヘルパーと同様にcontrollerに対して2つの値を引き渡す必要があります。
quantityidです。
しかも今回はquantity1という固定の定数を渡したいという状況でした。
link_toメソッドもfrom_withと同様にurlを書く時に値を渡すことができます。
但し、form_withヘルパーの場合はformで入力された値一つとurlからの値一つという方法でした。
幸いlink_toメソッドからは値を二つ渡せることが調べて分かりました。

index.html.erbの抜粋(修正後)
<% @merchandises.each do |merchandise| %>
<%= link_to 'Add to cart', create_path(merchandise.id, quantity:1), class: "btn btn-outline-dark mt-auto" %>

調査をもとに修正したコードは上記になります。
create_pathの後ろに括弧書きで値を二つ記述することで値を渡せるようになりました。
params.png

以上、viewからcontrollerに値を渡す方法をご紹介しました。

日頃、Qiitaを含めた記事には助けられているので、少しでもお役に立てると嬉しいです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?