class ItemsController < ApplicationController
def index
# itemsテーブルの中身すべてを@itemsインスタンス変数に代入
@items = Item.all
end
# 新しいユーザーを登録する画面に移動
def new
# itemsテーブルに紐付いたインスタンスを作成し、インスタンス変数に代入
@item = Item.new
end
# new.htmlからpostで送信されたデータを受け取る
def create
# binding.pry
Item.create(name: item_params[:name], price: item_params[:price])
end
# Strong Parameter
private
def item_params
params.require(:item).permit(:name, :price)
end
end
<%= form_for @item, method: :post do |f| %>
<h1>ご購入商品の情報を入力</h1>
<p>商品名:<%= f.text_field :name %></p>
<p>値段:<%= f.text_field :price %></p>
<input type="submit" value="SENT">
<% end %>
上記のようなcontrollerファイルと、erbファイルがあったとする。
疑問に思ったこと
<%= form_for @item, method: :post do |f| %>
↑この1行だけでitems_controller.rb
のcreate
アクションにデータを飛ばせるって謎だな・・・(腑に落ちない)
人生逆転サロンで質問してみると、どうやらform_forメソッドが略されている模様。
↓略されているバージョン
<%= form_for @item, method: :post do |f| %>
<h1>ご購入商品の情報を入力</h1>
<p>商品名:<%= f.text_field :name %></p>
<p>値段:<%= f.text_field :price %></p>
<input type="submit" value="SENT">
<% end %>
↓略されていないバージョン
<%= form_for @item,
as: :item,
url: items_path,
html: { class: "new_item", id: "new_item" } do |f| %>
<h1>ご購入商品の情報を入力</h1>
<p>商品名:<%= f.text_field :name %></p>
<p>値段:<%= f.text_field :price %></p>
<input type="submit" value="SENT">
<% end %>
略されていないバージョンで、実際にどういうHTMLが生成されているか見てみよう↓
(略されているバージョンでも同じHTMLが作成されることは確認済み)
<form class="new_item" id="new_item" action="/items" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="gO1KEJfKfbzGU8aLVT6KnfErKHBdoTwXU97YPBXa/+Qm+XK+MTTOZVFJJ9AMINdRMaEIpq/oop1vPQL/ODMGIg==">
<h1>ご購入商品の情報を入力</h1>
<p>商品名:<input type="text" name="item[name]" id="item_name"></p>
<p>値段:<input type="text" name="item[price]" id="item_price"></p>
<input type="submit" value="SENT">
</form>
上記を1つずつ紐解いていくと・・・
url: items_path
→ action="/items"
html: { class: "new_item", id: "new_item" }
→ class="new_item" id="new_item"
f.text_field :name
→ <input type="text" name="item[name]" id="item_name">
f.text_field :price
→ <input type="text" name="item[price]" id="item_price">
「ん???じゃあ、as: :item
は何をしているの・・・?」と新たな疑問が浮かんだ
調べるとas:
はform_for
のオプションであり、これを指定することでparams
のハッシュのキーを上書きできるのだ
as: :kotonoha
に修正↓
<%= form_for @item,
as: :kotonoha,
url: items_path,
html: { class: "new_item", id: "new_item" } do |f| %>
<h1>ご購入商品の情報を入力</h1>
<p>商品名:<%= f.text_field :name %></p>
<p>値段:<%= f.text_field :price %></p>
<input type="submit" value="SENT">
<% end %>
params.require(:kotonoha)
に修正↓
class ItemsController < ApplicationController
def index
# itemsテーブルの中身すべてを@itemsインスタンス変数に代入
@items = Item.all
end
# 新しいユーザーを登録する画面に移動
def new
# itemsテーブルに紐付いたインスタンスを作成し、インスタンス変数に代入
@item = Item.new
end
# new.htmlからpostで送信されたデータを受け取る
def create
# binding.pry
Item.create(name: item_params[:name], price: item_params[:price])
end
# Strong Parameter
private
def item_params
params.require(:kotonoha).permit(:name, :price)
end
end
binding.pryで中身を見ると下記のようにデータを取り出せる
[1] pry(#<ItemsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"Fxno0T/Z44CIOmfkHAdxph2I9yHZUFtDI2Nsj5SC4X9aDep+aAgPAQeVJJJ+v5S3ePjpmW5t0SVN7NgkLcEGCw==", "kotonoha"=>{"name"=>"kotonoha", "price"=>"11111"}, "controller"=>"items", "action"=>"create"} permitted: false>
[2] pry(#<ItemsController>)> params[:kotonoha]
=> <ActionController::Parameters {"name"=>"kotonoha", "price"=>"11111"} permitted: false>
[3] pry(#<ItemsController>)> params[:kotonoha][:name]
=> "kotonoha"
これは面白い・・・(むずかしいですな〜〜〜!)
参考記事↓
https://techracho.bpsinc.jp/hachi8833/2017_04_20/38378