bootstrap-select-railsを試す

# bootstrap-select-railsとは

[bootstrap-select](https://developer.snapappointments.com/bootstrap-select/)という、selectを拡張するjQueryプラグインがあります。bootstrap-selectをRailsアプリケーションに導入するためのgemに[bootstrap-select-rails](https://github.com/Slashek/bootstrap-select-rails)があります。

# bootstrap-select-railsを試す
早速、試してみましょう。

## Railsアプリケーションを作る

[ホスト環境のRubyを使わずにDockerを使ってRails newする](https://qiita.com/ledsun/items/83fee24dea251bd3a3f3) を参考にして空のRailsアプリケーションを作成します。

### sprockets-railsを有効に

アセットファイルのコンパイルを有効にするためにsprockets-railsを有効にします。
`Dockerfile`でOSにインストールするapkパッケージに`nodejs`を追加します。

```yaml
FROM ruby:2.5-alpine

ENV BUILD_PACKAGES="curl-dev ruby-dev build-base" \
    DEV_PACKAGES="zlib-dev libxml2-dev libxslt-dev tzdata yaml-dev sqlite-dev" \
    RUBY_PACKAGES="ruby-json yaml nodejs"

# Update and install base packages and nokogiri gem that requires a
# native compilation
RUN apk update && \
    apk upgrade && \
    apk add --no-cache --update\
    $BUILD_PACKAGES \
    $DEV_PACKAGES \
    $RUBY_PACKAGES && \
    mkdir -p /usr/src/myapp

# Copy the app into the working directory. This assumes your Gemfile
# is in the root directory and includes your version of Rails that you
# want to run.
WORKDIR /usr/src/myapp
COPY Gemfile /usr/src/myapp
COPY Gemfile.lock /usr/src/myapp

RUN gem install bundler
RUN bundle config build.nokogiri --use-system-libraries && \
    bundle install --jobs=4 --retry=10 --clean
```

rails newのオプションを次のように変更します。

```sh
docker run --rm -v (pwd):/usr/src/myapp temp rails new . -f -MCTBS --skip-yarn
```

## 編集画面を作る

編集画面があれば何でもいいので、[いつも忘れる「Railsのgenerateコマンド」の備忘録 - maeharinの日記](https://maeharin.hatenablog.com/entry/20130212/rails_generate)の


```sh
rails generate scaffold AdminUser name:string mail:string
```
をそのまま実行します。

```sh
docker run --rm -v (pwd):/usr/src/myapp temp rails generate scaffold AdminUser name:string mail:string
```

Railsを起動して、上手く編集画面が作れているか確認しましょう。

```sh
docker run --rm -it -v (pwd):/usr/src/myapp -p 80:3000 temp bin/rails s -b 0.0.0.0
```

http://localhost/admin_users を開きます。

![スクリーンショット 2019-05-17 17.01.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/114f18a0-3f16-14c3-94e9-0094e3efce69.png)

## フォームにselectを追加

`app/views/admin_users/_form.html.erb`を編集して`select`要素を追加します。

```erb
<%= form_with(model: admin_user, local: true) do |form| %>
  <select>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Barbecue</option>
  </select>
<% end %>
```

次のような見た目になります。

![スクリーンショット 2019-05-17 17.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/a4e1f6d9-504b-8d8b-402d-5087862c0b3b.png)

htmlのselect要素のままの見た目です。


## bootstrap-select-railsの導入

bootstrap-select-railsはjqueryとbootstrapに依存しています。
`Gemfile`に次の行を追加します。

```
gem 'jquery-rails'
gem 'bootstrap'
gem 'bootstrap-select-rails'
```

`bootstrap`gemを使うには`jquery`と`popper`と`bootstrap-sprockets`が必要です。
これに`bootstrap-select`を加えて、`application.js`に次の行を追加します。

```js
//= require jquery
//= require popper
//= require bootstrap-sprockets
//= require bootstrap-select
```

`bootstrap`gemを使うには、scssにする必要があります。
`application.css`を`application.scss`にリネームし、次の内容に変更します。

```scss
@import "bootstrap";
@import 'bootstrap-select';
```

`app/views/admin_users/_form.html.erb`を編集して`select`要素に`selectpicker`クラスを追加します。

```erb
<%= form_with(model: admin_user, local: true) do |form| %>
  <select class="selectpicker">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Barbecue</option>
  </select>
<% end %>
```
![スクリーンショット 2019-05-17 17.24.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/b3bcfddc-b240-f4e9-d9d4-1388686af6bf.png)

見た目が少し格好よくなりました:clap:
selectを開くと次のイメージです。

![スクリーンショット 2019-05-17 17.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/515e5d98-e553-bd77-7bc0-f3466eeea033.png)


## Turbolinks 5 対応

今の状態では http://localhost/admin_users/new を直接開くと期待通りに動きます。
一度 http://localhost/admin_users を開いてから `New Admin User`リンクをたどって新規追加画面を開くと、次のように期待しない動作をします。

![スクリーンショット 2019-05-17 17.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/3b3c4f12-2736-bdc9-59d1-658ba2da1b71.png)

[Do not work with Turbolinks 5 well · Issue #31 · Slashek/bootstrap-select-rails](https://github.com/Slashek/bootstrap-select-rails/issues/31)を参考にしてして、`application.js`に次のように変更します。

```js
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
//= require jquery
//= require popper
//= require bootstrap-sprockets
//= require bootstrap-select

$(document).on('turbolinks:load', function() {
   $(window).trigger('load.bs.select.data-api');
});
```

これで、一度 http://localhost/admin_users を開いてから `New Admin User`リンクをたどって新規追加画面を開いたときも、期待通りに動きます。:clap::clap:

# おまけ
この記事の実体は https://github.com/Slashek/bootstrap-select-rails/issues/31#issuecomment-480559605 で
> This solution doesn't work for version 1.13.8. 

と書かれていたので、「そんなことあるのかな？」と思い、動作確認するための環境を作る手順でした。

https://github.com/ledsun/sample-application-for-verifying-the-solution-for-bootstrap-select-rails-to-work-with-Turbolinks-5. で完成したソースコードを公開しました。