Rails 7: 2 つのボタン (GET リクエスト用と POST リクエスト用) を持つフォーム
概要
私はRuby on Railsアプリケーションに取り組んでおり、フォームをデザインしました。
フォームにはボタンが 2 つあります。
GET リクエストは正常に動作しており、コントローラーのインスタンス変数に params 値を保存することで、パラメーター値に対する操作を直接実行できます。
ただし、「保存」ボタンをクリックしたときにフォームのパラメータをモデルに保存することも必要です。
これを行うのに苦労しており、いくつかの方法を試しましたが、私の思考プロセスが正しいかどうかわかりません。
以下はフォームコードです。
形状:
<%= form_with url: home_homepage_path, method: :get do |f| %>
<div class="row">
<div class="form-group col-6">
<b>LOWER SPECIFICATION LIMIT (LSL):</b>
<%= f.number_field :lower_specification_limit, placeholder: "Enter lower specification limit", class: 'form-content form-content w-100 p-1' %>
</div>
<div class="form-group col-6">
<b>UPPER SPECIFICATION LIMIT (USL):</b>
<%= f.number_field :upper_specification_limit, placeholder: "Enter upper specification limit", class: 'form-content form-content w-100 p-1' %>
</div>
</div>
<div class="row">
<div class="form-group col-12">
<b>PROCESS TIME:</b>
<%= f.text_field :process_time_array, multiple: true, placeholder: "Enter process time. This value could be an array.", class: 'form-content form-content w-100 p-1' %>
</div>
</div>
<br/>
<div class="actions">
<%= f.submit 'Generate Plot', class: 'btn btn-block btn-outline-dark rounded-0' %>
<%= link_to "SAVE", home_save_plot_path, method: :post , class: 'btn btn-block btn-outline-dark rounded-0' %>
</div>
<% end %>
これらのフォームパラメータをコントローラのメソッドに渡して、データを操作モデルに保存しようとしています。以下に示すように、コントローラーにもメソッドを定義しました。
def save_plot
@operation = Operation.new
@operation = Operation.new(params[:upper_specification_limit, :lower_specification_limit, :process_time_array])
@operation.save
end
また、ルートについては以下のように記載しました。
post 'home/save_plot'
観察:
パラメーター データがフォームに保存されません。 「created_at」と「updated_at」のみが保存されます。
解決策
必要な数のボタンを用意します。
<%= f.submit "Generate",
formmethod: :get,
formaction: home_homepage_path
%>
<%= f.submit "Save",
formmethod: :post,
formaction: home_save_plot_path
%>
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/submit#additional_attributes
おそらく、ルート上の家が少ない方が良いかもしれません。
# config/routes.rb
Rails.application.routes.draw do
root "home#show"
resources :plots, only: [:create, :show] do
new do # you're making a new plot
get :preview # you want to take a peek
end
end
end
# $ bin/rails routes -g "home|plot"
#
# Prefix Verb URI Pattern Controller#Action
# root GET / home#show
# preview_new_plot GET /plots/new/preview(.:format) plots#preview
# plots POST /plots(.:format) plots#create
# plot GET /plots/:id(.:format) plots#show
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def show
end
end
# app/views/home/show.html.erb
<%= form_with model: Plot.new do |f| %>
<%= f.text_field :name %>
<%= f.submit "Generate",
formmethod: :get, # get it, don't post
formaction: preview_new_plot_path, # any path works, `home_homepage_path`
data: {turbo_frame: :plot_preview} # but get a frame only
%>
<%= f.submit "Save" %>
<% end %>
<%= turbo_frame_tag :plot_preview do %>
hit generate to see plot
<% end %>
さて、おそらく Plot モデルはありませんが、プロットの作成は PlotsController ジョブのように思えます。
bin/rails g scaffold_controller Plot
プレビュー アクションを追加します。
# app/controllers/plots_controller.rb
class PlotsController < ApplicationController
# GET /plots/new
def new
@plot = Plot.new
end
# GET /plots/new/preview
def preview
@plot = Plot.new(plot_params)
end
# POST /plots
def create
@plot = Plot.new(plot_params)
respond_to do |format|
if @plot.save
format.html { redirect_to plot_url(@plot), notice: "Created." }
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
private
def plot_params
params.fetch(:plot, {}).permit(:name)
end
end
[生成] をクリックすると、plot_preview フレームが次のように更新されます。
# app/views/plots/preview.html.erb
<%= turbo_frame_tag :plot_preview do %>
<%= @plot.name %>
<% end %>