Railsで画像を選択するとidが送られるフォームを作りたい(ラジオボタンを画像で選択させる)

# 概要
こんな感じのItemモデルへの投稿フォームの作りました。
画像を押すと選択され、もう一度押すと選択が解除されます。

<img width="300" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/ace04904-7034-e9ca-bfe1-ca9eaa18a6ab.jpeg">

投稿すると送られるパラメーター

```
Parameters: {"item"=>{"title"=>"青い玉", "ball_id"=>"2"}, "commit"=>"投稿"}
```


# 各モデルの構成

#### Itemモデル
タイトルとball_idを登録するテーブルです。

`belongs_to :ball`



#### Ballモデル
３種類のボールが画像と共に既にデータベースに登録済みとします。

`has_many :items`

| ID | NAME | IMAGE |
|:-----------|------------:|:------------:|
| 1       | Red        | Red.png         |
| 2     | Blue      | Blue.png       |
| 3       | Green        | Green.png         |


# コード


```application_helper.rb
module ApplicationHelper
  #引数(モデル名とnameカラム)をもとに、idを返すメソッド
  def return_id_by_model_and_name(model, name)
    model.constantize.find_by(name: name).id
  end
end
```


### html.erb
HTMLにonclick属性を使うのはあまり良くありませんが、実験ということで。
本当はイベントリスナーやイベントハンドラを使った方が良いです。

```erb
<h1>新規投稿</h1>
<%= form_with model: @item, local: true do |f| %>
  <h4 class="text-xl font-bold">タイトル</h4>
  <%= f.text_field :title %>

  <h4 class="text-xl font-bold">カラー</h4>
  <div class="boxContainer">

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Red"),{class:"radio_btn_to_image Red",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Red")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Red")}", class:"remove_inner_html" %>
      <p>Red</p>
    </div>

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Blue"), {class:"radio_btn_to_image Blue",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Blue")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Blue")}", class:"remove_inner_html" %>
      <p>Blue</p>
    </div>

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Green"), {class:"radio_btn_to_image Green",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Green")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Green")}", class:"remove_inner_html" %>
      <p>Green</p>
    </div>

  </div>

  <%= f.submit '投稿', class:"px-2 bg-blue-600 text-white" %>
<% end %>

```

### CSS
```css

.boxContainer{
  display: flex;
}

.radio_btn_to_image+label:before{
  content: "";
  display: inline-block;
  background-size: contain;
  width: 80px;
  height: 80px;
}

.radio_btn_to_image:checked+label::before{
  border: 3px solid #000;
  box-sizing: border-box;
}

.radio_btn_to_image{
  display: none;
}

.radio_btn_to_image[class="radio_btn_to_image Red"]+label:before{
  background-image: url(/images/balls/Red.png); /*画像は/public/images/balls/に置いている*/
  background-repeat: no-repeat;
}
.radio_btn_to_image[class="radio_btn_to_image Blue"]+label:before{
  background-image: url(/images/balls/Blue.png);
  background-repeat: no-repeat;
}
.radio_btn_to_image[class="radio_btn_to_image Green"]+label:before{
  background-image: url(/images/balls/Green.png);
  background-repeat: no-repeat;
}

```

### JavaScript

```javascript
let ball_remove = 0;
function ballDeselection = (self, value) => {
  if(ball_remove == value) {
    self.checked = false;
    ball_remove = 0;
  } else {
    ball_remove = value;
  }
};
```

## 参考にさせていただいたサイト
https://mgmgblog.com/?p=1935