52
60

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ruby on Rails】collection_check_boxes で 詰まったから...

Last updated at Posted at 2018-01-24

はじめに

Rails 4.0.2以降から使用できる
ViewHelper の collection_check_boxes を使用しようとして少し詰まったので、
簡単なアプリケーションを作成してみて、楽しく覚えてみた。

環境

  • Ruby: 2.4.0
  • RoR: 5.0.6
  • haml

やりたいこと

User を 作成するときに 飲み物(Drink)を 選択して create できる。

プラスα - 選択肢にない飲み物(Drink)が 出てきたら 飲み物も新規登録できるように。

2018-01-24 17.14.15.png

いわゆる、

パシリの為の パシリによるアプリケーション


- タケシは、 コーラ。
- サトルは、コーヒーと水。
- ハナコは、お茶。

あれ、、、全部覚えてられないな。。。orz

やってみた

scaffold で User, Drink, DrinkUser を 作成
多 対 多 の関係性を 記していく。

Model

user.rb

class User < ApplicationRecord

  has_many :drink_users
  has_many :drinks, through: :drink_users
  accepts_nested_attributes_for :drink_users, allow_destroy: true


end

drink.rb

class Drink < ApplicationRecord

  has_many :drink_users
  has_many :users, through: :drink_users

end


drink_user.rb

class DrinkUser < ApplicationRecord

  belongs_to :user, optional: true
  belongs_to :drink, optional: true

end


Controller

users の new に Drink を 用意しておく

users_controller.rb
class UsersController < ApplicationController

  def new
    @user = User.new
    @drinks = Drink.all
  end

... ... ... ...

  private

  def user_params
    params.require(:user).permit(:name, drink_ids: [])
  end

end

scaffold で 作成された Controllerに
@drinks = Drink.all (チェックボックスの選択に使用)と
StrongParametersに drink_ids: [] (配列のパラメーターを許可) を足した。

View

users/_from.haml

= form_for(user) do |f|
  - if user.errors.any?
    #error_explanation
      %h2
        = pluralize(user.errors.count, "error")
        prohibited this user from being saved:
      %ul
        - user.errors.full_messages.each do |message|
          %li= message
  .field
    = f.label :name
    = f.text_field :name

    = f.collection_check_boxes :drink_ids, @drinks, :id, :name, include_hidden: false do |b|
      = b.label { b.check_box + b.text }

  .actions
    = f.submit


= f.collection_check_boxes の チェックボックスの記述を追加。

Seed

db/seeds.rb

%W[コーヒ コーラ お茶 紅茶 ミルクティ 水].each { |a| Drink.create(name: a) }

よく お頼みになる飲み物を seedファイルで予め用意しておく。
rails db:seed の実行を忘れずに。

drinks_tables.
+----+--------------------+---------------------+---------------------+
| id | name               | created_at          | updated_at          |
+----+--------------------+---------------------+---------------------+
|  1 | コーヒ               | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  2 | コーラ               | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  3 | お茶                | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  4 | 紅茶                | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  5 | ミルクティ            | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  6 | 水                 | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
+----+--------------------+---------------------+---------------------+

-----------------------

これだけで
/users/newに アクセスすると、
人の名前を入力して、飲みモノを 選んで, データを作成することができる。



collection_check_boxes の使い方

下記、HTMLのような、チェックボックスを collection_check_boxesを使用して、いい感じに表示させる。

sample.html
<form action="cgi-bin/abc.cgi" method="post">
  <p>
    <input type="checkbox" name="riyu" value="1">選択肢 - 1
  </p>
  <p>
    <input type="checkbox" name="riyu" value="2">選択肢 - 2
  </p>
  <p>
    <input type="checkbox" name="riyu" value="3">選択肢 - 3
  </p>
  <p>
    <input type="submit" value="送信する">
  </p>
</form>

スクリーンショット
2018-01-24 18.16.03.png

collection_check_boxes を用いてみる


check_boxes.haml

= form_for(user) do |f|
  = f.label :name
  = f.text_field :name

  = f.collection_check_boxes :drink_ids, @drinks, :id, :name do |b|
    = b.label { b.check_box + b.text }

  = f.submit '送信', class: 'btn'

btn.css

.btn{
    display: inline-block;
    padding: 0.5em 1em;
    text-decoration: none;
    background: #668ad8;
    color: #FFF;
    border-bottom: solid 4px #627295;
    border-radius: 3px;
}


スクリーンショット
2018-01-24 15.17.29 1.png

なんだか、チェックボックス と テキストの感覚が ギュン と近すぎて気持ち悪い...orz


check_boxes.haml

= form_for @user do |f|
  = f.collection_check_boxes :reason_ids, @choices, :id, :content do |b|
    = b.check_box
    = b.label { box.text }
  = f.submit '送信', class: 'btn'


スクリーンショット

2018-01-24 15.06.16.png

いい感じになった☺

Option

上記の form のままだと パラメーターの配列の先頭に ' '
空の 値が含まれるので, option で

check_boxes_option.rb
  f.collection_check_boxes :reason_ids, @choices, :id, :content, include_hidden: false do |b|

のように option で 先頭の空の値をなくすことができる。

また, 1行で 書くこともできる

check_boxes_one_line.rb
  = f.collection_check_boxes :drink_ids, @drinks, :id, :name, include_hidden: false, class: 'hoge'

1行で書くと, classなど html のoptionの与え方がややこしくなるので、僕は ネストさせた方が好きです。


余談

users_table.

+----+-----------+---------------------+---------------------+
| id | name      | created_at          | updated_at          |
+----+-----------+---------------------+---------------------+
|  1 | タケシ     | 2018-01-24 09:22:21  | 2018-01-24 09:22:21 |
|  2 | サトル     | 2018-01-24 09:22:41  | 2018-01-24 09:22:41 |
|  3 | ハナコ     | 2018-01-24 09:23:11  | 2018-01-24 09:23:11 |
+----+-----------+---------------------+---------------------+

drinks_table.

+----+--------------------+---------------------+---------------------+
| id | name               | created_at          | updated_at          |
+----+--------------------+---------------------+---------------------+
|  1 | コーヒ               | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  2 | コーラ               | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  3 | お茶                | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  4 | 紅茶                | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  5 | ミルクティ            | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
|  6 | 水                 | 2018-01-24 09:01:14 | 2018-01-24 09:01:14 |
+----+--------------------+---------------------+---------------------+

drink_users_table.

+----+----------+---------+---------------------+---------------------+
| id | drink_id | user_id | created_at          | updated_at          |
+----+----------+---------+---------------------+---------------------+
|  1 |        2 |       1 | 2018-01-24 09:22:21 | 2018-01-24 09:22:21 |
|  2 |        1 |       2 | 2018-01-24 09:22:41 | 2018-01-24 09:22:41 |
|  3 |        6 |       2 | 2018-01-24 09:22:41 | 2018-01-24 09:22:41 |
|  4 |        3 |       3 | 2018-01-24 09:23:11 | 2018-01-24 09:23:11 |
+----+----------+---------+---------------------+---------------------+

こんな感じ🤔

スクリーンショット
2018-01-24 18.35.20.png

drinks/new も動かせば, 飲み物の選択肢を 増やすことができるので、イレギュラーにも対応できます☺



### 参考
52
60
1

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
52
60

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?