yuuichi-code / kamutora_farm

0 stars 0 forks source link

キャラクター選択フォームで選択後、renderすると入力値が保持されない #54

Open yuuichi-code opened 1 year ago

yuuichi-code commented 1 year ago

質問内容

collection_selectのフォームの入力値をrenderで再表示させても入力値を保持させたい。

現状発生している問題

3個あるcollection_selectのフォームの入力値がrenderで再表示させると、選択がされていない状態になってしまう。

どの処理までうまく動いているのか

3個あるcollection_selectのフォームの入力値が@post_form.selected_charactersに配列で送れている。

該当のソースコード

以下ビューのコード

<%= form_with model: @post_form, url: create_step1_path, local: true do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="my-10 sm:mx-auto sm:w-full sm:max-w-sm">
    <%= f.label :title, class: 'block text-gray-700 text-sm font-bold mb-2' %>
    <%= f.text_field :title, class: 'shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline' %>
  </div>
  <div class="flex justify-center">
    <div class="flex">
    # 以下の3つのフォームが該当の部分になります
      <%= f.collection_select :selected_characters[0], @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>
      <%= f.collection_select :selected_characters[1], @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>
      <%= f.collection_select :selected_characters[2], @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>
    </div>
  </div>
  <div class="flex justify-center mt-8 ml-48">
    <%= f.submit (t '.next_step'), class: 'rounded-lg border border-gray-300 bg-white px-5 py-2.5 text-center text-sm font-medium text-gray-700 shadow-sm transition-all hover:bg-gray-100 focus:ring focus:ring-gray-100 disabled:cursor-not-allowed disabled:border-gray-100 disabled:bg-gray-50 disabled:text-gray-400' %>
  </div>
<% end %>

以下フォームオブジェクトのコード

class PostForm
  include ActiveModel::Model

  attr_accessor :title, :selected_characters

  validates :title, presence: true

end

以下コントローラーのコード一部抜粋

  def step1
    @post_form = PostForm.new
    @characters = Character.all
  end

  def create_step1
    @post_form = PostForm.new(post_params)
    @characters = Character.all
    @post_form.valid?

    render :step1, status: :unprocessable_entity
  end

  private

  def post_params
    params.require(:post_form).permit(:title, selected_characters: [])
  end

実際の挙動

https://gyazo.com/4ec182152b4caf0ea428fd2aaae9e49e

試したこと

  def create_step1
    @post_form = PostForm.new(post_params)
    @characters = Character.all
    @post_form.valid?
    # 一旦止める
    binding.b
    render :step1, status: :unprocessable_entity
  end

フォームの入力値を確認するために上記のように一旦止めて、post_paramsを確認したところ

<ActionController::Parameters {"title"=>"test", "selected_characters"=>["2", "3", "4"]} permitted: true>

となっているので問題なくデータは送れていると思います。 @post_form.selected_charactersも確認してみたところ ["2", "3", "4"] というようにしっかりと配列になっています。

    <%= f.collection_select :selected_characters, @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>
    <%= f.collection_select :selected_characters, @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>
    <%= f.collection_select :selected_characters, @characters, :id, :name, { prompt: t('.choice') }, { name: 'post_form[selected_characters][]' } %>

のように:selected_charactersの[0][1][2]を削除してrenderで再表示してみると 以下の動画のように最後に選択した値が3個のフォームに同じ値が保持されてしまいます。 https://gyazo.com/2deae9e65482bb6df88aacf88fe91acf

yuuichi-code commented 1 year ago

技術面談で一旦別案で進めることになったため保留