20190523のRubyに関する記事は19件です。

Windows10 で WSL を使って Rails 環境を構築したときのメモ

はじめに

本記事の趣旨はタイトルの通り。
WSL( Windows Subsystem for Linux ) 環境で Rails 環境を構築したときのメモ。

本記事を実施した環境

ツール バージョン 確認方法
Windows 10 Home 64bit
Windows Subsystem for Linux
Ubuntu 18.04.2 LTS (Bionic Beaver) $ cat /etc/os-release
rbenv 1.1.2-2 $ rbenv -v
Ruby 2.6.1p33 $ ruby -v
Rails 5.2.3 $ rails -v
gem 3.0.1 $ gem -v
Bundler 2.0.1 $ bundler -v
n 4.1.0 $ n --version
Node.js 10.15.3 $ node -v
npm 6.4.1 $ npm -v

WSL( Windows Subsystem for Linux ) を入れよう

WIndows 10 の Professional でも Home でも WSL は入れられる。
WSL の導入は次の記事に従って作業すればスムーズに行えた。

WSL を入れたら

1. 環境を最新にしよう

Ubuntu のターミナルから次のコマンドを実行して環境を更新する。
sudo はスーパーユーザでの実行権限を付与するコマンド。apt-get は管理者権限での実行が必要なので、sudoをつけて実行する。

環境を更新する
$ sudo apt-get update
$ sudo apt-get upgrade

Rails 環境を構築しよう

注意

ご使用の環境で Kaspersky が起動していると以降の作業で通信を行う際にエラーとなって各種ツールのインストールやRailsプロジェクトの作成に失敗する。

ここでは Kaspersky を停止して作業を継続した。

1. 各種ライブラリを入れよう

rbenv を入れた あとに rbenv 経由で Ruby を入れるのだが、その際に ruby-build という rbenv のプラグインを入れる 必要がある。
で、その ruby-build のインストールにあたって色々と必要なライブラリがある。
ここでは実際に Ruby を入れる際に発生する余計なエラーを回避すべく、それらを事前に入れておく。

各種ライブラリのインストール
$ sudo apt-get install make
$ sudo apt-get install gcc
$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev

2. Node.js を入れよう

こちらも同じく事前にエラーを回避するための手順。
Rails を実行する際に JavaScript のエンジンが必要になるのだが、 Node.js を入れておくことでこれに対応できる。

(注)
これはあくまで WSL 上の Ubuntu における環境構築手順なので、Windows 上ですでに Node.js を入れていてもこの手順は実施する必要がある。

インストールは次のコマンドを実行する。

Node.jsのインストール
$ sudo apt-get install npm

これで Node.js そのものはインストールされたのだが n というツールを入れることで Node.js のバージョン管理を行うことができる。
n のインストールは次のコマンドを実行する。

nのインストール
$ sudo npm install -g n
$ sudo n stable

(注)
手前味噌で恐縮だが、n による Node.js のバージョン管理については 別記事 で記載しているので、ご興味あればそちらも参照されたい。
そちらの記事では LinuxMint 18 が確認環境だが、同じ Debian ベースのデストリビューションなので違和感なく進められると思う。

3. rbenv を入れよう

どうせやるなら rbenv で Ruby のバージョンを管理したい。
ということで、 rbenv を GitHub から git clone で取ってくる。

rbenvをインストール
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

rbenv がインストールできたら次のコマンドを実行して rbenv の PATH を通す。

rbenvのPATHを通す
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc

そして次のコマンドを実行して rbenv の設定を行う。

rbenvの設定を行う
$ ~/.rbenv/bin/rbenv init

と打つと

実行結果
# Load rbenv automatically by appending
# the following to ~/.bashrc:

eval "$(rbenv init -)"

とでるので、eval "$(rbenv init -)".bashrc に追記する。
まとめると、.bashrc には次の2行が追記されることになる。

追記される2行
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

最後にターミナルを再起動して環境変数の反映させる。
( $ source ~/.bashrc か、もしくは $ exec $SHELL -l でも反映できる )

4. ruby-build を入れよう

rbenv をインストールしたら次は Ruby を入れるためのプラグイン、 ruby-build を入れる。

ruby-buildをインストール
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

ここで 先の手順 でインストールしたライブラリが効いてくる。
これらのライブラリを入れていない場合は、逐次エラーが発生してその都度ライブラリをインストールしなければならず、非常に鬱陶しい。

5. Ruby を入れよう

ようやく Ruby のインストールである。
Ruby のバージョンは任意のもので良い。ここでは 2.6.1 を入れてみる。
次のコマンドを実行して Ruby のバージョン 2.6.1 をインストールする。

Rubyのバージョン2.6.1をインストール
$ rbenv install 2.6.1
$ rbenv rehash
$ rbenv global

で、Ruby のバージョンは。。。

Rubyのバージョンを確認
$ ruby -v
ruby 2.6.1p33 

と、指定したバージョン( 2.6.1 ) がインストールされていることが確認できた。

6. Rails を入れよう

Ruby のインストールまで終わったら、次は Rails を入れるための作業にはいる。
Rails は gem 経由でインストールする。バージョンは指定しない。

Railsのインストール
$ gem install rails
Fetching railties-5.2.3.gem
/home/hogehoge/.rbenv/rbenv.d/exec/gem-rehash/rubygems_plugin.rb:6: warning: Insecure world writable dir /home/hogehoge/.rbenv/versions in PATH, mode 040777
Successfully installed railties-5.2.3
Successfully installed rails-5.2.3
Parsing documentation for railties-5.2.3
Installing ri documentation for railties-5.2.3
Parsing documentation for rails-5.2.3
Installing ri documentation for rails-5.2.3
Done installing documentation for railties, rails after 0 seconds
2 gems installed

ということで、2019年05月現在、5.2.3 のバージョンがインストールされた。
既存の Rails プロジェクトにあわせたバージョンを指定したい場合は次のように指定してやれば良い。
( ここでは 5.2.0 を指定した )

Railsのインストール(バージョン指定)
$ gem install rails --version="5.2.0"

7. sqlite を入れよう

Rails を使うにあたり SQLite3 のインストールが必要になる。SQLite そのものは gem 経由でインストールするのだが、ここでも依存ライブラリを先に入れておかなければならない。

まずは依存ライブラリのインストールから。

SQLite3の依存ライブラリのインストール
$ sudo apt-get install libsqlite3-dev

次に SQLIte3 のインストール。

SQLite3のインストール
$ gem install sqlite3 -v 1.3.13

8. bundler を入れよう

Rails では一旦プロジェクトを作ると、そのプロジェクトで扱っているライブラリは Gemfile で管理され、それらは bundler でインストールすることになる。
ということで、 bundler をインストールしておく。

bundlerのインストール
$ gem install bundler

Rails プロジェクトを作ろう

1. Rails プロジェクトを作ろう

ここまでで Ruby のインストールと Rails のインストール、およびそれらを使う際に必要な最低限のライブラリのインストールが完了した。
実際に Rails プロジェクトを作って起動してみる。

プロジェクトの作成は次のコマンドで行う。

Railsのプロジェクト作成
$ rails new sample-app

2. Rails プロジェクトを起動しよう

これで雛形ができたので、プロジェクト直下に移動してアプリケーションを起動する。

Railsアプリの起動
$ cd sample-app/
$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.1 (ruby 2.6.1-p33), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

あとはブラウザから http://localhost:3000 にアクセスして、次のページが見れれば環境構築は完了。

rails_app.png

Windows のフォルダにシンボリックリンクを貼って Rails プロジェクトを Windows から編集しよう

上記までで Ubuntu on WSL の環境に Rails を導入できたが、このままだと Windows 環境から Rails プロジェクトの編集ができない。

Ubuntu から Windows のフォルダは /mnt/c/ から参照できるので、Rails のプロジェクトを Windows 側のフォルダに作成してそこを Ubuntu 側で参照しに行っても良いが、毎回 /mnt/c から参照しにくのは流石に面倒臭い。

ということで、シンボリックリンクである。
ここでやることの目的は

  • Ubuntu から Windows への参照の手間を減らすこと

で、やることは以下の2つ。

  1. あらかじめ Windows のユーザホームフォルダ直下に Rails フォルダを作成しておく
  2. Ubuntu のユーザホームディレクトリから Rails フォルダに対してシンボリックリンクを貼る

以下の作業で lns -s を実行し、Rails をフォルダにシンボリックリンクを貼る。

シンボリックリンクを貼る
$ pwd
/home/hoge                      # Ubuntu 上のホームディレクトリ
$ ln -s /mnt/c/Users/hoge/Rails # シンボリックリンクを貼る

ls -l を実行すると、

シンボリックリンクを確認
$ ls -l
total 0
lrwxrwxrwx 1 hoge hoge 27 May 22 23:15 Rails -> /mnt/c/Users/hoge/Rails

上記のとおり、Windows のフォルダに対してシンボリックリンクが貼れている。

あとはシンボリックリンクを貼ったフォルダに対して

  • 既存の Rails プロジェクトをここに移動させる
  • ここで Rails プロジェクトを新たに作成する

等を行うことで、Windows から Rails プロジェクトを編集することができる。

これで

  • Rails アプリの管理は Ubuntu on WSL
  • Rails アプリの編集は Windows

という構成ができた。

所感

気分によって今日は Mac、今日は Windows という感じで作業ができると嬉しいと思い、Windows での Rails 環境構築を実施してみた。
とりあえずこれで Windows で Rails の開発ができるようになったはずなので、これから遊んでみようと思う。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

credentials.yml.encでシークレットキーを管理

はじめに

Rails5.2からsecrets.ymlが廃止され、credentials.yml.encに統合されたことをメンターの方に教えて頂いたため、API Keyなどのシークレットキーをcredentials.yml.encにまとめた。
恥ずかしい話、今まではENV["hogehoge.key"]と書いてシークレットキーを~/.bash_profileにまとめていた。
もちろん、アプリごとにシークレットキーを管理したほうが良い(当たり前だが)ので、今回行ったcredentials.yml.encの設定に関する一連の流れを備忘録として残しておく。

編集方法

credentials.yml.encを開いてみると、

config/credentials.yml.enc
msb4Uzo8vfnzbP65VQ58Hmu4o5WzNDTVqv9EFRnR5.....

このように暗号化されて直接編集することはできない。

credential.yml.encを編集するにはbin/rails credentials:editを実行する。
エディタを指定する必要があるので、今回はコマンドでEDITOR="vi" bin/rails credentials:editと入力。

初期値は以下の通り。

Terminal
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: o8vfnzbP65VQ58Hmu4o5WzNDTVqv9EFRnR5.....

AWS等各種サービスで発行されたシークレットキーをここに入力する。
変更が完了すると、再びcredential.yml.encが暗号化されキーの値が変わる。

読み取り方法

各種シークレットキーをアプリ内で読み取る場合、Rails.application.credentials.aws[:access_key_id]のように入力する。(以下コード参照)
尚、初期値はコメントアウトされているため、読み取る際には外しておくこと。

Terminal
aws:
  access_key_id: 65VQ58Hmu4o5WzNDT...
  #=> Rails.application.credentials.aws[:access_key_id]
  secret_access_key: DTVqv9EFRnR...
  #=> Rails.application.credentials.aws[:secret_access_key]

secret_key_base: 8be8e637d755f79c799048bed8be0c...
#=> Rails.application.credentials.secret_key_base

本番環境(Heroku)でのシークレットキーの読み取り

暗号化されているcredential.yml.encを読み取る際にはmaster.keyが必要となる。
しかし、master.keyはRails5.2において.gitignoreに標準指定されているため、そのままでは本番環境でcredential.yml.encを読み取ることはできない。
よってHerokuで読み取る際にはheroku config:set RAILS_MASTER_KEY=マスターキーの値をコマンドで入力しマスターキーの値を指定する。

config/environments/production.rb
config.require_master_key = true

上記のように設定することで、本番環境におけるマスターキーが指定されていない場合にエラー表示を出すことができる。

基本的にcredential.yml.encの用途は「本番環境での秘匿情報の管理」だが、各環境で別々に秘匿情報を管理するためのrails-env-credentialsというgemもあるらしい。

参考

Railsガイド セキュリティ10.1-独自のcredential
Rails5.2から追加された credentials.yml.enc のキホン

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】コピペで使えるdevise備忘録

はじめに

deviseでユーザーログイン機能を追加するにあたって、普段よく使っているものの備忘録です。

rootをログイン画面に設定

deviseのcontrollerを作成し、routes.rbで以下のように設定。

$ rails g devise:controllers users
routes.rb
Rails.application.routes.draw do

   # rootをログイン画面に設定
  devise_scope :user do
    root "users/sessions#new"
  end

  devise_for :users, :controllers => {
    sessions: 'users/sessions'
  }

ログイン後のpathを指定

application_controller.rbで以下を記載。

application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_in_path_for(resource)
    tasks_path
  end

このようにログイン後最初のページを条件分岐させることも可能です↓

application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_in_path_for(resource)
    if admin_user?
      users_path
    else
      tasks_path
    end
  end

ストロングパラメーターのpermit

deviseではサインアップ時にemailとpassword系のみを受け取るようにストロングパラメーターが設けられているので、それ以外の :name などを許可したい場合↓

application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

.
.
.


  private

  def configure_permitted_parameters
    added_attrs = [ :name,
                    :email,
                    :password,
                    :password_confirmation,
                  ]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
    devise_parameter_sanitizer.permit :sign_in, keys: added_attrs
  end

おわり

他にも備忘録しておきたい事ありそうなので、思い出し次第追加したいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

1日1問解いてSQLをマスター!SQLの学習サービス Qdash を作った話

目次

  • はじめに
  • なぜ作ろうと思ったか
  • 使ってる技術
  • 同じようなサービスを作りたい人のために実装を紹介
    • 1日に1回、指定の時間に問題を切り替えて表示する
    • 質問箱風なOGP画像を生成
  • これから
  • 最後に

はじめに

Qdash という1日1問形式の SQL 学習サービスを作りました。

https://q-dash.jp

問題画面

スクリーンショット 2019-05-21 12.18.08.png

回答画面

スクリーンショット 2019-05-21 12.18.37.png

なぜ作ろうと思ったか

とあるデータを見たいけど、いつも SQL を書ける人にお願いしている。
勉強はしたいが、中々勉強する時間が取れない。

と思ってるディレクター、営業、マーケターの方!!
でも1日の中でも隙間時間はありますよね?

その隙間時間に問題を解き、SQL は任せて!と自信を持って言えるようになりませんか?
というのがサービスのコンセプトです。

使っている技術

・ Ruby
・ Rails
・ ServiceWorker / Webpush
・ Heroku

Rails / Heroku で手早く作りました。
push 通知をするために ServiceWorker と Webpush にも挑戦しました。 (この記事では触れません)

実装紹介

似たようなサービスを作りたい人のために実装をいくつか紹介します!

1日に1回、指定の時間に問題を切り替えて表示する

SQL を学びたい人にとって負担にならないように1日1問という仕様にしました。
あなたならどのように実装しますか?

今回は Cookie と Heroku scheduler を使って実装してみました。

class HomeController < ApplicationController
  def index
    @question = today_question
    delete_cookie_if_question_changed

    @answer = Answer.find_by(id: answer_id)
  end

  private

    # flesh set by scheduler.rake
    def today_question
      today_question = TodayQuestion.last || TodayQuestion.create_randomly
      today_question.question
    end

    def delete_cookie_if_question_changed
      answer = @question.answers.find_by(id: answer_id)
      cookies.delete('answer_id') if answer.nil?
    end

    def answer_id
      cookies['answer_id']
    end
end

回答をした際に cookie をセットします。

class AnswersController < ApplicationController
  def create
    answer = Answers::Factory.build(answer_choice_params)
    if answer.save
      cookies['answer_id'] = answer.id
      redirect_to root_path
    else
      redirect_to root_path, notice: '回答に失敗しました。'
    end
  end

  private

    def answer_choice_params
      params.permit(:answer_choice_id)
    end
end

Heroku scheduler で1日1回、今日の問題をDBに登録しています。
時間と実行するコマンドはアドオンを入れた後に Heroku の管理画面から設定することができます。

# sheduler.rake

task set_question_randomly: :environment do
  TodayQuestion.create_randomly
end

昨日と同じ問題が出たらテンションが下がるのでそれは避けるようにしています。

class TodayQuestion < ApplicationRecord
  belongs_to :question

  def self.create_randomly
    question = nil

    loop do
      last_question = TodayQuestion.last.question
      question = Question.pick_randomly

      break if last_question.id != question.id
    end

    create(question: question)
  end
end

質問箱風なOGP画像を生成

続いて、質問箱風な OGP の生成処理です。
問題の作成時に問題のタイトルを画像に書き込み、画像を S3 にアップロードします。 (active_storage を利用)

そして、シェアした時に作成した問題文が書かれたOGP画像が表示されるようにします。

# Gemfile
gem 'mini_magic'
class OgpImageGenerator
  def initialize(question: question)
    @question = question
  end

  def generate
    image = load_base_image
    image.combine_options do |c|
      c.gravity 'West'
      c.pointsize 30
      c.draw "text 55,0 '#{title}'"
      c.size "70x"
      c.fill '#000'
      c.font Rails.root.join('public', 'hiraginokakugoW6.ttc').to_s
      c.interline_spacing 10
      c.kerning 4
    end
    image
  end

  private

    def title
      ApplicationController.helpers
                           .sanitize(@question.title)
                           .chars.each_slice(15)
                           .map(&:join)
                           .join("\n")
    end

    def load_base_image
      MiniMagick::Image.read(Rails.root.join('public', 'images', 'ogp_base.png'))
    end
end
class Question < ApplicationRecord
  ..
  before_save :generate_ogp_image
  before_update :generate_ogp_image

  has_one_attached :ogp_image

  def generate_ogp_image
    return unless self.will_save_change_to_title?

    ogp_image_path = OgpImageGenerator.new(question: self).generate.path
    file = File.open(ogp_image_path)

    self.ogp_image.attach(
      io: file,
      filename: "question_ogp_image_#{id}_#{SecureRandom.urlsafe_base64}.png", content_type: "image/png"
    )
    file.close
  end
end

スクリーンショット 2019-05-21 12.17.04.png

問題を作成すると、このような OGP 画像が自動で生成されます。

これから

ログイン機能とコース機能を作って問題を解けるようにしたいと思っています。
ログインしていなくても問題を解くことができる一方で、熱量の高い人はログインしてまとまった時間で勉強できたら良いですね。

実は一番大変なのは機能の実装より SQL の問題を作ることだったりしますw

最後に

詳細な使い方については note に書いているので見ていただけたら幸いです。
https://note.mu/usabdelah/n/n0b7f8fd30ed5

Qdash で学んだことを活かして実務で SQL を書き、
データの可視化をやっていく人が増えたらいいなと思っています。

ぜひ、Qdash で SQL の問題を解いてみてください。

https://q-dashjp

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails hands on

rails で Web アプリを作ってみよう!

Web アプリを作って、動かして、触って、デプロイしてみよう!

事前準備

docker , bundler はインストールしておいてね

docker

bundler

docker-compose.yml
Dockerfile
docker

をローカルにコピー
TODO: curl でダウンロードできるようにする

やってみよう!

$ mkdir rails_sample && cd rails_sample
$ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker .
remove `Gemfile.lock` in Dockerfile
$ bundle init
$ docker-compose run --rm web bundle exec rails new . -d mysql --skip-test

ここで今日のゴールを
https://rails-sample-fot-lt.herokuapp.com/users/sign_in
(今日はログインやらんけど)

ログインあり&デプロイありの、ハンズオンやりたいと思う人!

希望あれば日程調整しましょう
3時間ぐらい
うまくいけば30分

edit database.yml

  pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %>
  username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
  host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %>
  port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>

add Gemfile.lock in Dockerfile

$ docker-compose up
$ docker-compose exec web bin/rails g scaffold post content
$ docker-compose exec web bin/rails db:migrate

hands on メモ

$ mkcd rails_sample
$ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker .

remove Gemfile.lock in Dockerfile

$ bundle init
$ docker-compose run --rm web bundle exec rails new . -d mysql --skip-test
create remote repository
$ cp -a ~/Download/Gemfile  .

edit database.yml

database.yml
  pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %>
  username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
  host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %>
  port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>

add Gemfile.lock in Dockerfile

$ docker-compose up
$ docker-compose exec web bundle install
$ docker-compose exec web rails generate simple_form:install
$ docker-compose exec web rails haml:erb2haml
$ docker-compose exec web rails g annotate:install
$ docker-compose exec web bin/rails g scaffold post content
$ docker-compose exec web bin/rails g scaffold user name
$ docker-compose exec web bin/rails db:migrate
$ docker-compose exec web bundle exec rails generate devise:install

add

    %p.notice= notice
    %p.alert= alert

in app/views/layouts/application.html.haml

$ docker-compose exec web bundle exec rails g devise:views
$ docker-compose exec web rails generate devise user
$ docker-compose exec web bin/rails db:migrate

add before_action :authenticate_user! in app/controllers/posts_controller.rb and app/controllers/users_controller.rb

add root to: 'post#show' route.rb

access http://localhost:3000/users

heroku deploy

create app in gui

$ heroku login
$ heroku git:remote -a rails-sample-fot-lt
$ git push heroku master
$ heroku addons:create cleardb:ignite
$ heroku config | grep CLEARDB_DATABASE_URL

mysql://[username]:[password]@[hostname]/[db_name]?reconnect=true

$ heroku config:add DB_NAME="[db_name]"
$ heroku config:add DB_USERNAME="[username]"
$ heroku config:add DB_PASSWORD="[password]"
$ heroku config:add DB_HOSTNAME="[hostname]"
$ heroku config:add DB_PORT="3306"
$ heroku run rake db:migrate

コピー用

Dockerfile
FROM ruby:2.6.2

RUN apt-get update --fix-missing \
  && apt-get -y upgrade \
  && apt-get install -qq -y \
    nodejs \
    mysql-client \
  && apt-get autoremove -y \
  && apt-get clean all \
  && fc-cache -f -v

# Add dumb init to process system events
RUN wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 -O /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init

RUN gem update --system
RUN gem install bundler

WORKDIR /rails_sample
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs=4 --retry=3

COPY . .

EXPOSE 3000

# Start the main process.
CMD bin/rails server -b 0.0.0.0
docker-compose.yml
version: '3.7'

services:
  db:
    restart: always
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 3306:3306
    volumes:
      - ./docker/mysql/conf:/etc/mysql/conf.d:rw
      - dbdata:/var/lib/mysql

  web:
    build: .
    depends_on:
      - db
    volumes:
      - .:/rails_sample
      - "bundle:/usr/local/bundle"
    environment:
      - MYSQL_HOST=db
    command: >
      bash -c "
        bundle install --quiet &&
        docker/bin/start rails"
    ports:
      - 3000:3000

volumes:
  bundle:
  dbdata:
docker/mysql/conf/default_authentication.cnf
[mysqld]
default_authentication_plugin=mysql_native_password
docker/bin/rails
#!/bin/sh

docker-compose run --rm backend bin/rails "$@"
docker/bin/start
#!/bin/sh

if [ $# = 0 ]; then
  echo "usage:"
  echo "  start rails:              Start rails server"
  echo "  start rails recreate db:  Start rails server recreate db"
  echo "  start sidekiq:            Start sidekiq process"
  echo "  start sidekiq-web:        Start sidekiq web server"
  exit 1
fi

case "$1" in
  "rails")
    bundle exec rails tmp:pids:clear
    bundle exec rails log:clear tmp:clear
    bundle exec rails server --port 3000 --binding "0.0.0.0"
    ;;
  "rails recreate db")
    bundle exec rails tmp:pids:clear
    bundle exec rails db:reset
    bundle exec rails db:migrate
    bundle exec rails log:clear tmp:clear
    bundle exec rails server --port 3000 --binding "0.0.0.0"
    ;;
  "rails migrate db")
    bundle exec rails db:migrate
    ;;
  "sidekiq")
    bundle exec sidekiq
    ;;
  "sidekiq-web")
    bundle exec rackup --host "0.0.0.0" --port 9292 lib/sidekiq_web/config.ru
    ;;
esac
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby最新版の挙動をRSpec+Guardで試した時の環境構築メモ

はじめに

Rubyのバージョンが上がったときなどにサクッと挙動を確かめられるよう書いた自分用のメモです
(ちなみにbrewやRubyをインストールする時間を除けば3分で構築できました)

今回利用したツールの各バージョン

  • macOS 10.13.6
  • brew 2.1.3
  • rbenv 1.1.2

最新Rubyインストール

インストールできるRubyのバージョンリストを最新にする

brew update && brew upgrade ruby-build

インストール可能な一覧を見てバージョンを決める

rbenv install -l
...
2.7.0-dev
...

指定したバージョンのインストール

rbenv install 2.7.0-dev

作業場所用意

ここで「sample」という作業ディレクトリを作り
以下の作業はこの中で行います

mkdir ~/sample
cd ~/sample

インストールしたバージョンに切り替える

rbenv local 2.7.0-dev
ruby -v #=> ruby 2.7.0dev (2019-05-22 trunk ca435ed04a) [x86_64-darwin17]

RSpec + Guardインストール

まずはbundlerインストール

gem install bundler
bundler -v #=> Bundler version 2.1.0.pre.1

Gemfile新規作成

bundle init # Gemfileが生成される

Gemfileに必要なgem追記

Gemfile
# 以下追記
gem "rspec"
gem "guard"
gem "guard-rspec"

gemインストール

.bundle/ にインストールすることにします

bundle config set path .bundle # ちなみに --path .bundleは非推奨になるらしい
bundle install

今回は以下のバージョンがインストールされました

  • rspec (3.8.0)
  • guard (2.15.0)
  • guard-rspec (4.7.3)

RSpec準備

bundle exec rspec --init

Guard準備

bundle exec guard init

テストコード作成

> spec/my_spec.rb
spec/my_spec.rb
require 'spec_helper'

RSpec.describe 'MySample' do
  describe 'methodメソッド' do
    subject { 123.method(:to_s) }
    it { expect(subject.class).to eq(Method) }
    it { expect(subject.call).to eq('123') }
    it { expect(subject.()).to eq('123') }
  end

  describe 'メソッド参照演算子' do
    subject { 123.:to_s }
    it { expect(subject.class).to eq(Method) }
  end
end

Guard起動

bundle exec guard

とりあえずenter押せば全テストケースを実行してくれます。
あとはlib/my_spec.rbを保存するたびにテストコードが走るはずです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Sass】導入と使い方

はじめに

ポートフォリオを作るにあたりcssを書こうと思ったのですが、
sassというものがあると知ったので導入しました。
途中、エラーが出たところもまとめます。

sassとは何か

sassの導入

私はmacを使っているのでRubyの導入では何もしてません。

sassインストール

Sassを使ってCSSを爆速コーディング!Sassの導入方法と使いかた。に書いてある通り、
下記コマンドを実行するが

$ gem install sass

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.

エラー...

gem installでpermissionエラーになった時の対応方法
こちらの記事の現状確認と同じコマンドを実行すると、全く同じ結果が返ってきました。

なので私もrbenvというやつを入れます。(rubyのバージョン管理をしてくれるものなのかな..)
記事の通り、最新版のrubyをインストールしたので、私の場合は2.6.3です。

$ rbenv install 2.6.3

$ rbenv versions
* system (set by /Users/hoge/.rbenv/version)
  2.6.3

この後からは先ほどの記事とは違うことを行いました!

記事では、rbenvでインストールしたrubyのバージョンをglobalにしていますが、
他のアプリに影響を与えたくないので今回はlocalで利用します。

$ cd ver2.6.3のrubyを使いたい作業ディレクトリ
$ rbenv local 2.6.3

$ rbenv versions
  system (set by /Users/hoge/.rbenv/version)
* 2.6.3

その後パスを通します。
~/.bash_profileにeval "$(rbenv init -)"を追記します。

パスを更新したいので、

$ source ~/.bash_profile
$ ruby -v
  ruby 2.6.3

できました!

今回はglobalでなくlocalにしているので、
rbenv local 2.6.3コマンドを実行したディレクトリ下でのみこのバージョンが適応されます。

今度こそSassインストール

$ gem install sass

できた...

使い方

Sassを使ってCSSを爆速コーディング!Sassの導入方法と使いかた。
こちらの記事の実際に使ってみるを参考にしました!
私はscssにしました。

参考にしたサイト(ありがとうございます><)

これからはcssはSassで書こう。
Sassを使ってCSSを爆速コーディング!Sassの導入方法と使いかた。
gem installでpermissionエラーになった時の対応方法
rbenvでバージョンがうまく切り替わらなかった時にやったこと

使ってみて

cssで書くよりもきれいに書けるのと、みやすいのでこれからもガンガン使っていきたいです!
参考になるサイトがたくさんあって助かりました。ありがとうございます。

ポートフォリオサイトを少しだけ更新しました。
FontAwsomやtwitterタイムラインを載せたので、手順やメモをまた投稿しようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【自分用】railsでhello, world!するまでの備忘録

Railsインストールからhello, world!出力までのもくじ

  1. rbenvを使ってRubyとRuby on Railsをインストール ※前提として、Command line tools をターミナルからインストール済 xcode-select --install
  2. コードを編集するのに必要なテキストエディタをインストール
  3. hello, world!を出力するだけの単純アプリの作成

1.rbenvを使ってRubyとRuby on Railsをインストール

1-1.Homebrewをインストール

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

ターミナルのスクショ
スクリーンショット 2019-05-23 14.14.50.png

1-2.rbenvをインストール

まずはrbenvをインストール
brew update
brew install rbenv

ターミナルのスクショ
スクリーンショット 2019-05-23 14.22.37.png

rbenvのインストールが完了したら、rbenvにパスを通します
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

ターミナルのスクショ
スクリーンショット 2019-05-23 14.40.38.png

1-3.rbenvを使ってRubyをインストール

下記コマンドでrbenvでインストール可能なRubyのバージョンを確認
rbenv install -l

実際にコマンド打つとこんな感じ↓
スクリーンショット 2019-05-23 14.47.30.png
※実際にはもっと表示されます

現在の安定版を確認するならwww.ruby-lang.orgにアクセスすると良いです。
スクリーンショット 2019-05-23 14.55.12.png
※スクショは2019年5月23日時点での安定板なので最新の安定板は↑のリンクに実際にアクセスして確認してください。

現在の安定板の確認をしたらrbenvを使ってRubyをインストール
rbenv install 2.6.3

ターミナルのスクショ
スクリーンショット 2019-05-23 14.49.35.png

1-4.デフォルトのRubyを設定

rbenv global 2.6.3

ターミナルのスクショ
スクリーンショット 2019-05-23 15.02.40.png

1-5.Railsのインストール

gem install rails

ターミナルのスクショ
スクリーンショット 2019-05-23 15.05.53.png

2.コードを編集するのに必要なテキストエディタのインストール

Atomエディタ使ってる人多い印象なのでAtom.ioからダウンロード。

3.hello, world!を出力するだけの単純アプリの作成

3-1.プロジェクトで使うディレクトリenvironmentを作成

今回のプロジェクトで使うディレクトリenvironmentを作成し、environmentディレクトリに移動。

mkdir environment
cd environment

ターミナルのスクショ
スクリーンショット 2019-05-23 16.15.01.png

3-2.移動先のディレクトリenvironmentでアプリケーションの作成

下記コマンドの_5.1.6_のところではrailsのバージョンを明示的に指定)。

rails _5.1.6_ new hello_app```
Traceback (most recent call last):
    2: from /Users/masaki-sakamoto/.rbenv/versions/2.6.3/bin/rails:23:in `<main>'
    1: from /Users/masaki-sakamoto/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/Users/masaki-sakamoto/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem railties (= 5.1.6) with executable rails (Gem::GemNotFoundException)

コマンド実行したらGemNotFoundExceptionというエラーが発生しましたが、下記コマンドを実行したら解消され無事hello_appの作成完了。

gem install rails -v 5.1.6

3-3.rails sコマンドでhello, world!を出力

作成したhello_appのディレクトリに移動し、rails sコマンドを実行。

rails s

アプリケーションを表示するには、ローカルサーバーの場合http://localhost:3000/をブラウザで開きます。
※Ctrl+Cを押すとサーバーを終了できる
実際に開くとこんな感じ↓
スクショ
スクリーンショット 2019-05-23 17.21.18.png

用語まとめ

後日追記予定

参照リンク

Rails Girls インストール・レシピ
最初のアプリケーション
railsチュートリアルでのエラー

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】実務未経験がプルリクエスト時レビュアーに指摘されたこと-コミット・RSpec編-

はじめに

実務未経験の自分がエンジニアスクールでレビューを頂いた時に、
おそらく現場でも指摘されるであろう項目をまとめていきます。

前回は、コード・文法編をまとめました。
【初心者向け】独学では気づきにくい!実務未経験がプルリクエスト時レビュアーに指摘されたこと-コードお作法編-

まとめきれていない部分もありますので、随時追記していきます。
特に、独学でRails等を学んでいる方の参考になれば幸いです。

1. コミットでの注意

わかりやすく、綺麗なコードを書くことは心がけているに、雑なコミットで残してませんか?
私が独学で勉強していた頃は、正直疎かにしてました。
しかし、プルリクエストでレビューしてもらう際やチーム開発では、理解しやすいコミットを残す必要があります。
特にコレが正解!というのはありませんが、指摘されたことを踏まえてまとめていきます。

1-1. 1つのコミットで複数の機能を追加するのは避けよう。(意図を理解しづらくなる)

一気に複数の機能を実装して、1つのコミットにまとめると見る側が意図を理解しづらくなります。

$ git commit -m "ログイン機能、ユーザー編集機慧能、画像投稿機能およびRspecテストを追加"

のようにしてしまうと、
メッセージ的にもコードを確認するにしても分かりづらい状況になります。
コミットをどのように分けるかは、常に意識する必要があります。

1-2. 理解しやすいコミットメッセージ

コミットメッセージには、端的に理解しやすいメッセージで残す必要があります。

  • どういう目的で
  • 何を
  • どうしたのか(追加・修正・更新・削除など)

をコミットメッセージに残せると見る側も意図を理解しやすそうです。
とはいえ、チーム・プロジェクトによりルールがあると思われますので注意が必要。
個人的には以下のURLで紹介されていた書き方が分かりやすいかなと感じました。

参考URL: 誰にとってもわかりやすいGitのコミットメッセージを考える

1-3. 不要なファイルは除外or削除しよう

自動生成されるけど不要なファイルは事前に必要かどうかを考えましょう。
そして、本番環境で不要な.env(環境変数)などのファイルは、事前に.gitignoreに記述して除外しておきましょう。
不要なファイルがコミットされれば、自分・レビュアー共に見づらいプルリクエストになってしまう。

2. RSpecの準備編<導入後>

Gemfile
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end

で、bundle install後に準備すると良いものをまとめます。
基本設定などは、[Qiita] Ruby on Rails のテストフレームワーク RSpec 事始めなどがオススメです。

2-1. 結果を見やすくする

通常何も設定せずにRSpecテストをすると

...

Finished in xx seconds
3 examples, 0 failures

テストに失敗していないことは分かりますが、詳細が分かりにくい状態に。
そんな時は、
.rspecformat documentationを入れて結果を見やすくすると良い。
※個人的にもレビューをして頂いている方にも見やすいテスト結果になります。

.rspec
--require spec_helper
--format documentation

例えば、このように出力されます。

Sample::HomeController
  Home Controller indexの機能テスト
    sample/に正常にアクセスできる

Sample::ProductsController
  Prodcut Controller showの機能テスト
    products/showに正常にアクセスできる
    @productが取得できている

Finished in xx seconds
3 examples, 0 failures

2-2. FactoryBotを設定しておく

RSpecでFactoryBotを使う場面があると思います。
何も設定をしない状態では、

  let!(:product) { FactoryBot.create(:product) }

FactoryBotを毎回書く必要があります。
これでは、作業効率的にあまり良くないので、rails_helper.rb定義しておくと良いです。

spec/rails_helper.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

見た目もすっきりして、呼び出せるようになりました。

  let!(:product) { create(:product) }

詳しい設定方法などは、こちらの記事がオススメです。
参考URL: RailsアプリへのRspecとFactory_botの導入手順

3. RSpecのお作法編

RSpecを書いていく上で指摘されたお作法についてまとめています。

3-1. テストの文言を考える

機能単体テスト(feature test)で考えれば、

  • featureは「どのような機能」
  • scenarioは「ユーザーから見たサービスの挙動」

ということを踏まえて文言を考える。
‌例)

feature '商品の詳細ページを見ることが出来る' do
  scenario '詳細ページにアクセス時、商品名や価格などの情報が表示される' do
  end
  scenario "関連商品をクリック時、商品詳細ページへ移動する" do
  end
end

適当な文言設定をすると分かりにくいテストになり、確認する側も意図を理解するのに時間がかかります。

参考URL:
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」

3-2. 検査するDOM(HTML)の範囲を絞る

withinを使うことで、対象範囲を指定することができます。
これにより正確に意図したテストを実行することができます。
例は以下になります。

# id="add_to_cart"で探せるようにする
<div id="add_to_cart" class="btn-area">
  <%= link_to cart_page_path do %>
    <div class="btn btn-primary btn-block">
      カートへ入れる
      <i class="fa fa-angle-right" aria-hidden="true"></i>
    </div>
  <% end %>
</div>
scenario "カートを入れるをクリック時、買い物カゴページへ移動する" do
# id="add_to_cart"の範囲を指定したテストをする
  within "#add_to_cart" do
    click_on "カートへ入れる"
  end
#現在のページがカートページであることを確認
  expect(page).to have_current_path cart_page_path
end

参考URL:
Capybaraチートシート#スコープを切る

3-3. RSpecを設置するディレクトリを考える

分かりやすいディレクトリ構成にすると良いでしょう。
例えば、
app/controllers/products_controller.rbに対応するRSpecは、
rspec/requests/products/products_controller_spec.rb
が分かりやすい。

RSpecテストのファイルが多くなってくると、一目でファイルを探すのに苦労する場面も。
分かりやすいディレクトリ構成にすることで、ストレスを少しは軽減できると思います。

まとめ

今回は、コミット・RSpecで注意された点をまとめました。
まだ、細かい点などもありますので、まとめ次第追記いたします。
RSpecについては、独学で学習している頃は苦手意識があり敬遠していましたが、
指摘されることで少しずつ理解が深まってきた印象です。

現場等でエンジニアをやられている方で、本記事に間違い等ございましたら、
大変恐縮でありますがご指摘いただければと存じます。
よろしくお願いいたします。

RSpecの勉強に使用した著書:
「Everyday Rails - RSpecによるRailsテスト入門」

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails5でMySQLのid以外にbigint + primary key + auto increment する。(migration)

やり方

調べたところRails4の頃の情報しか見当たらず、漁ると

auto_increment オプションが搭載されたことにたどり着く。

cerate_tableでの:idに続けざまに書くことで対応可能となるらしい。

以下は、PKをcompany_idにした会社マスタのサンプルである。

/db/migrate/example.rb
def change
  create_table :m_company, primary_key: "company_id", id: :bigint, comment: "会社ID", auto_increment: true, default: nil, force: true, comment: '会社マスタ' do |t|
    ## t.bigint :company_id, null: false, comment: '会社ID' ※←ここには書かない
    t.string :name, null: false, comment: '会社名'
    t.text :detail, comment: '内容'
    t.datetime :created_at, null: false, comment: '作成日時'
    t.datetime :updated_at, null: false, comment: '更新日時'
  end
end

以下となる。

mysql> desc m_company;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| company_id | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | NO   |     | NULL    |                |
| detail     | text         | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

あとから変えたい場合は、change_columnで入る

こんな感じ。rollbackできるようにupとdownで書く

/db/migrate/example.rb
def up
  change_column :m_company, :company_id, :primary_key, auto_increment: true
end
def down
  change_column :m_company, :company_id, :bigint
  execute "ALTER TABLE m_company DROP PRIMARY KEY;"
end

問題 コメントが入らない

create_tableでPKを作成してしまうと、テーブルのコメントはかけてもPKカラムのコメントが入らない。(comment:オプションが被るから)

ので、

/db/migrate/example2.rb
def up
  create_table :m_company, primary_key: "company_id", id: :bigint, auto_increment: true, default: nil, force: true, comment: '会社マスタ' do |t|
    t.string :name, null: false, comment: '会社名'
    t.text :detail, comment: '内容'
    t.datetime :created_at, null: false, comment: '作成日時'
    t.datetime :updated_at, null: false, comment: '更新日時'
  end
  change_column :m_company, :company_id, comment: "会社ID"
end

def down
  # change_column :m_company, :company_id, comment: nil ※コメントだけ追加ならばこれ
  drop_table :m_company
end

これでコメントも追加できる”が”、schema.rbを確認するとわかるように
change_columnの内容がcreate_tableにマージされてしまっているのがわかる。

ゆえに、db:setupをした場合は、PKのキーにコメントが入らないためdb:migrateをすることをお勧めする。

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails5でMySQLのid以外にbigint + primary key + auto increment する。(migration)

やり方

調べたところRails4の頃の情報しか見当たらず、漁ると

auto_increment オプションが搭載されたことにたどり着く。

cerate_tableでの:idに続けざまに書くことで対応可能となるらしい。

以下は、PKをcompany_idにした会社マスタのサンプルである。

/db/migrate/example.rb
def change
  create_table :m_company, primary_key: "company_id", id: :bigint, comment: "会社ID", auto_increment: true, default: nil, force: true, comment: '会社マスタ' do |t|
    ## t.bigint :company_id, null: false, comment: '会社ID' ※←ここには書かない
    t.string :name, null: false, comment: '会社名'
    t.text :detail, comment: '内容'
    t.datetime :created_at, null: false, comment: '作成日時'
    t.datetime :updated_at, null: false, comment: '更新日時'
  end
end

以下となる。

mysql> desc m_company;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| company_id | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | NO   |     | NULL    |                |
| detail     | text         | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

あとから変えたい場合は、change_columnで入る

こんな感じ。rollbackできるようにupとdownで書く

/db/migrate/example.rb
def up
  change_column :m_company, :company_id, :primary_key, :bigint, comment: "会社ID", auto_increment: true, default: nil
end
def down
  change_column :m_company, :company_id, :integer, comment: nil, auto_increment: false
end

問題 コメントが入らない

create_tableでPKを作成してしまうと、テーブルのコメントはかけてもPKカラムのコメントが入らない。(comment:オプションが被るから)

ので、

/db/migrate/example2.rb
def up
  create_table :m_company, primary_key: "company_id", id: :bigint, auto_increment: true, default: nil, force: true, comment: '会社マスタ' do |t|
    t.string :name, null: false, comment: '会社名'
    t.text :detail, comment: '内容'
    t.datetime :created_at, null: false, comment: '作成日時'
    t.datetime :updated_at, null: false, comment: '更新日時'
  end
  change_column :m_company, :company_id, comment: "会社ID"
end

def down
  # change_column :m_company, :company_id, comment: nil ※コメントだけ追加ならばこれ
  drop_table :m_company
end

これでコメントも追加できる”が”、schema.rbを確認するとわかるように
change_columnの内容がcreate_tableにマージされてしまっているのがわかる。

ゆえに、db:setupをした場合は、PKのキーにコメントが入らないためdb:migrateをすることをお勧めする。

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

実務未経験からRails開発に途中参加した際の環境構築

 はじめに

実務未経験から内定をいただいた企業のrailsでの開発に途中参加することになり、環境構築を行う中で躓いた部分があったため振り返り用として記録します。

  環境

  • プログラミングスクールにてRuby、Railsの環境構築済み
  • データベースはMySQLを使用
  • GitHubアカウント登録済
  • Homebrew、rbenvインストール済み
  • mac OS使用

 前提

  • 与えられた情報はGitHubのリポジトリのみ
  • ローカル環境で起動できることを目標とする

やったこと

GitHubリポジトリの共有

1.プライベートリポジトリを共有するためGitHubに登録しているアドレス又はアカウント名を伝える
2.GitHubのリポジトリへ招待され参加する
3.ローカルリポジトリの作成

開発環境構築

1.Ruby、Rails等のバージョンを開発環境に合わせる

Ruby、Railsのバージョンなどは 「Gemfile」 で確認をします

Gemfile
ruby '2.5.0'

gem 'rails', '~> 5.2.0'
gem 'pg', '>= 0.18', '< 2.0'
gem 'sass-rails', '~> 5.0'

ここではRubyのバージョンを合わせます
自分のPCにインストールしているバージョンを確認

$ rbenv install --list
Available versions:
  1.8.5-p52
  1.8.5-p113
  :

下記コマンドで変更したいバージョンを指定
インストールしていた場合

$ rbenv local 2.6.0

インストールしていない場合

$ rbenv install 2.6.0

バージョンも合わせ、いざ Gemをインストール 

$ bundle install

そしたらこんなエラーが…
何やらpgがインストールされてないとか?

An error occurred while installing pg (1.1.3), and Bundler cannot
continue.
Make sure that `gem install pg -v '1.1.3' --source 'https://rubygems.org/'`
succeeds before bundling.

pgってなんだというところから検索し…データベースがPostgreSQLであることがは判明!!
こちらを参考にインストール

ターミナルでコマンドを打ち

$ sudo gem install pg -v '1.1.4' --source 'https://rubygems.org/'

またしてもエラー…
エラー内容は忘れましたがこちらを参考にし解決(恐らく同じエラーでした)

$ brew install postgresql

2.PostgreSQLも無事インストールできたので再度Gemをインストール

$ bundle install

3.データベース作成

$ bundle exec rake db:create

4.マイグレーションファイルの実行

$ bundle exec rake db:migrate

5.PostgreSQLを起動

$ postgres -D /usr/local/var/postgres

6.サーバーを起動

$ rails s

これで無事にローカル環境構築完了!!

 ※手順としては前後している可能性がありこれが正しいとは限りませんのでご了承ください

 おわりに

プログラミング初心者として検索していく中で、同じような状況の人の手助けになればと思い記事にしました。
やり方としてはエラーに遭遇しながら手探り状態で調べて進めたため進め方おかしいぞとなるかもしれません。

 参考

https://qiita.com/nasutaro211/items/d69a5e0b883293537b7e#_reference-a0cf0f3d167d682de2dc
https://qiita.com/youcune/items/5b783f7fde45d0fd4b35
https://qiita.com/yh2020/items/8be3087004d100fe752b

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Tutorial(2週目)-4-

4章はチェリー本に書いてあることがほとんどだったので、また別でまとめようと思います。

アクセサーの作成

attr_accessorは内部的に次のような処理を行っています。

(1)引数のシンボルすべてに対して以下の処理を繰り返す。

(2)シンボルで指定された名前のメソッドを定義する。そのメソッドはシンボルの名前の先頭に「@」を付加したインスタンス変数の値を取り出す。

(3)シンボルで指定されたメソッド名の後ろに「=」を付加した名前のメソッドを定義する。そのメソッドは引数を1つ取り,その値をシンボルの名前の先頭に「@」を付加したインスタンス変数に設定する

attr_accessor によってクラス外からも、インスタンス変数を読み込んだり、変更したり操作できるようになる。

ユーザー名とメールアドレス (属性: attribute) に対応するアクセサー (accessor) をそれぞれ作成します。アクセサーを作成すると、そのデータを取り出すメソッド (getter) と、データに代入するメソッド (setter) をそれぞれ定義してくれます。具体的には、この行を実行したことにより、インスタンス変数@nameとインスタンス変数@emailにアクセスするためのメソッドが用意されます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby + AWS】Amazon EC2インスタンスでLINE Bot Server構築してみた

はじめに

こんにちは。ここ最近ですが、仕事でLINE Botを作ることになりましたので、必要な設定を共有できればと思います。
なお、この記事ではあくまで概念とLINE Bot Serverを構築するまでの準備のレベルを書こうと思うので、あえてBot Server部分のコードは省略します(というか、書き始めたばかりなので新規に埋め込んだコードがほとんどない)。

追記

よくよく考えたら、概念図のポンチ絵、左部分おかしいですね、、、
LINEのネイティブ・WebアプリケーションがあってそこにユーザとBotがいるので、本来は入れ子にするべきでしたね。後日、修正します。

LINE Botの概念図

手書きのポンチ絵なのて、字が下手な部分はご愛嬌...
なお、このポンチ絵は以下の3つの資料を参考に書きました。

https://developers.line.biz/ja/docs/messaging-api/overview/
https://developers.line.biz/ja/docs/messaging-api/getting-started/
https://developers.line.biz/ja/docs/messaging-api/building-bot/

57748388-ba4a6600-7714-11e9-8fde-2082f833de7b.jpg

当初、弊社のWebアプリケーション用のサーバとは別にLINE PFがアクセスするエンドポイント用のサーバを用意する必要があったので、スクリプト言語で書く必要もないかなと考えGoでやろうかと言っていましたが、それほど大規模なアクセスを想定していないこと、既存のアプリケーションと一旦統合するような設計を採る事にしたため、RubyでBot Serverを作る事にしました。

環境の確認

  • OS: Amazon Linux AMI release 2018.03
  • Nginx: 1.14.1
  • Ruby: 2.4.6

Route 53でコールバック用に使うレコード名を登録 || セキュリティグループの設定

上記のLINE PF(プラットフォーム)がコールバック用のエンドポイントとなるURLにアクセスできるようにレコード名を登録してあげます。また、グローバルにアクセスできるようにSecurity Groupの設定も行って下さい。

EC2インスタンス上でLINE Bot Serverを設定

Bot Server検証用の環境を構築しようとした矢先に気づいたのですが、LINE Botではコールバック用のURLはHTTP over SSLしか対応していない事が発覚し、検証環境でもSSL証明書を導入する必要が出てきました。そのため、EC2インスタンス単体で証明書をインポートする機構が必要だったため、今回はLet's Encryptで導入する形を採りました。

SSL証明書の導入(Let's Encrypt)

基本的には、下記の部分のコマンドの引用です。

https://certbot.eff.org/lets-encrypt/centosrhel6-nginx

  • certbot-autoの導入
% wget https://dl.eff.org/certbot-auto
% sudo mv certbot-auto /usr/local/bin/certbot-auto
% sudo chown root /usr/local/bin/certbot-auto
% sudo chmod 0755 /usr/local/bin/certbot-auto
  • 証明書の発行
% sudo /usr/local/bin/certbot-auto --nginx certonly --debug
  • NGINXをリバースプロキシとして設定し、SSL証明書をインポート
server {
    listen       80;
    server_name  ***.***.***;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }
}

server {
    listen 443;
    ssl on;
    server_name ***.***.***;
    ssl_certificate /etc/letsencrypt/live/***.***.***/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/***.***.***/privkey.pem;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://127.0.0.1:3000;
    }
}
% sudo service nginx restart

RubyによるBot Serverの構築

LINEリポジトリから公式に提供されているhttps://github.com/line/line-bot-sdk-rubyというRuby用のBot Kitをインストールします。
なお、Bot Kitは、他にも多くの言語をサポートしている模様ですので、基本的なLINE Botの作り方は採用する言語に合わせてBot Kitを用意すればOKです。

echo botによる動作確認

各Bot Kitリポジトリのexamplesディレクトリ配下にサンプルコードが用意されています。今回は、echobotでユーザメッセージをそのまま鸚鵡返しするBot Serverを採用し、動作確認を行います。

https://github.com/line/line-bot-sdk-ruby/tree/master/examples/echobot

IMG_1413.jpg

echo Botによる動作確認が取れました。

まとめ

これまた、設定部分の所しかかけていませんが、これからどんどんコードを書いていこうと思います。

因みに、line-bot-sdkの事を、Bot Kitって言っているのは、プラモデルを作るのと同じように、「部品が用意されていて、それを組み合わせて静的なモデルを完成させる」感覚になっているので、ライブラリというよりツールキット(Bot用だからBot Kit)という言い方しています。

まぁ、そんな与太話はどうでもいいと思うので、中身を詳細に書き次第、改めて記事を書いていきます。
それではまた。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails hidden_fieldの渡し方、受けとり方

渡し方

値を指定する場合はvalueを使う。
第一引数にオブジェクト名、第二引数部分にvalueで受け渡す値を指定する。

text.html.erb
<%= f.hidden_field :unique_key, :value => params[:unique_key] %>

受け取り方

valueで渡した値をモデルのインスタンスの属性に格納している場合、以下のようになる。

text_controller.rb
@introduce = Follow.find_by(unique_key: params[:follow][:unique_key])

Followモデルのunique_keyカラムの値を受け取る場合。

参考

Ruby on Rails - hidden_fieldの使い方
https://qiita.com/azusanakano/items/5849a7ca74be58d195b7
f.hidden_fieldとhidden_field_tagの使い方【Ruby on Rails】
https://sakurawi.hateblo.jp/entry/hidden_field

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsアプリケーションをデプロイ&ロールバックするCapistranoコマンド

環境

$ cat /etc/system-release
Amazon Linux AMI release 2018.03

# プロジェクトのディレクトリ内にて
$ vim Gemfile.lock
capistrano (3.11.0)
unicorn (5.5.0)

$ rbenv versions
* 2.6.2 (set by /usr/local/rbenv/version)

$ bin/rails -v
Rails 5.2.3

はじめに

開発環境やステージング環境などデプロイ先によって、設定ファイル名はそれぞれstaging.rbdevelopment.rbになると思います。
今回はproduction.rbという本番環境の設定ファイルを使用して、デプロイ・ロールバックするという前提で話を進めます。

production.rb
server 'localhost', user: 'banri', roles: %w{ app web db }
set :rails_env, :production
set :unicorn_rack_env, "#{fetch(:rails_env)}"
set :deploy_to, '/var/www/hogehoge(アプリケーション名)/production'
set :repo_url, 'git@github.com:banri/hogehoge.git'
set :branch, :master

デプロイ?

デプロイの疎通確認?

$ bundle exec cap production deploy:check

以下のような結果になれば、デプロイ疎通OKです。

$ bundle exec cap production deploy:check
00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 banri@localhost 0.751s
      Uploading /tmp/git-ssh-Hogehoge-local-banri.sh 100.0%
      02 chmod 700 /tmp/git-ssh-Hogehoge-local-banri.sh
    ✔ 02 banri@localhost 0.754s
00:02 git:check
      01 git ls-remote git@github.com:banri/hogehoge.git HEAD
      01 Warning: Permanently added 'github.com,XX.XX.XXX.XX' (RSA) to the list of known hosts.
      01 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HEAD
    ✔ 01 banri@localhost 2.833s
00:05 deploy:check:directories
      01 mkdir -p /var/www/hogehoge/production/shared /var/www/hogehoge/production/releases
    ✔ 01 banri@localhost 0.706s
00:05 deploy:check:linked_dirs
      01 mkdir -p /var/www/hogehoge/production/shared/log /var/www/hogehoge/production/shared/tmp/pids /var/www/hogehoge/production/shared/tmp/cache /var/www/hogehoge/production/shared/tmp/sockets /var/www/hoge…
    ✔ 01 banri@localhost 0.745s
00:06 deploy:check:make_linked_dirs
      01 mkdir -p /var/www/hogehoge/production/shared/config
    ✔ 01 banri@localhost 0.760s

CapistranoのデプロイはSSHを使用します。接続ができずデプロイの疎通に失敗した場合は、以下のようなエラーを吐きます。

cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as banri@localhost: Authentication failed for user banri@localhost

Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user banri@localhost

SSHのセットアップなどに関しては、Connecting to GitHub with SSHを参考にしてください。

デプロイの実行???

$ bundle exec cap production deploy:check

Capistranoの公式ドキュメントによると、上記コマンド1発で以下のコマンドが順番に実行されているそうです。

$ bundle exec cap production deploy:starting     - デプロイスタート+全てのデプロイ準備ができているかの確認
$ bundle exec cap production deploy:started      - custom tasksへのデプロイフックの作成開始
$ bundle exec cap production deploy:updating     - 新リリースに伴うサーバーのアップデート → ここではcurrentディレクトリに同期されていない状態
$ bundle exec cap production deploy:updated      - デプロイフックのアップデート
$ bundle exec cap production deploy:publishing   - 新リリースの公開
$ bundle exec cap production deploy:published    - デプロイフックの公開
$ bundle exec cap production deploy:finishing    - デプロイ完了
$ bundle exec cap production deploy:finished     - デプロイフック作成完了

deploy:updatingのコマンド入力後、/releases以下を確認するとアプリケーションのバージョンが変わっていないことが分かります。
変わっていない場合は、本日の日付が入ったソースコードのディレクトリが存在しません。

$ cd /var/www/hogehoge/production/releases
$ ls -tl
total 20
drwxrwxr-x 16 banri banri 4096 Mar 15 05:57 20190315033559     - 最終更新のファイル名が本日の日付になっていないことを確認
drwxrwxr-x 15 banri banri 4096 Jan 12 03:58 20190112061458
drwxrwxr-x 14 banri banri 4096 Aug  3  2018 20180803054816
drwxrwxr-x 15 banri banri 4096 Jul  4  2018 20180704091354
drwxrwxr-x 14 banri banri 4096 Jul  4  2018 20180704082634

ロールバック?

1つ前のリリース状態へロールバック?

$ bundle exec cap production deploy:rollback

ロールバックも同様に、上記コマンド1発で以下のコマンドが順番に実行されているそうです。

$ bundle exec cap production deploy:starting
$ bundle exec cap production deploy:started
$ bundle exec cap production deploy:reverting              - 旧リリースへサーバーの巻き戻し
$ bundle exec cap production deploy:reverted               - デプロイフックの巻き戻し
$ bundle exec cap production deploy:publishing
$ bundle exec cap production deploy:published
$ bundle exec cap production deploy:finishing_rollback     - ロールバック完了
$ bundle exec cap production deploy:finished

特定のリリース状態にロールバック???

ROLLBACK_RELEASE=の後に、リリースのディレクトリ名を指定するだけです。

$ bundle exec cap production deploy:rollback ROLLBACK_RELEASE=リリースのディレクトリ名(日付)

例えば以下のような感じです。
$ bundle exec cap production deploy:rollback ROLLBACK_RELEASE=20190112061458

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6 のちょい足しな新機能を試す22(filter_attributes 編)

はじめに

Rails 6 に追加されそうな新機能を試す第22段。 今回のちょい足し機能は、 filter_attributes ( filter_attributes= メソッド)編です。
Rails 6.0 では、 filter_attributes で指定された model の attribute は [FILTERED] と表示されるようになります。

Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease でインストールできます。

$  rails --version
Rails 6.0.0.rc1

Rails プロジェクトを作る

$ rails new rails6_0_0rc1
$ cd rails6_0_0rc1

User model を作ります

$ bin/rails g model User name sensitive
$ bin/rails db:create db:migrate

config/initializers/filter_parameter_logging.rb を編集する

sensitive を [FILTERED] にするために filter_parameter_logging.rb を編集します。

config/initializers/filter_parameter_logging.rb
Rails.application.config.filter_parameters += [:password, :sensitive]

irb で確認する

irb で User モデルを作成して、確認すると、 sensitive の値が [FILTERED] となっていることがわかります。

bash-4.4# bin/rails c
Running via Spring preloader in process 50
Loading development environment (Rails 6.0.0.rc1)
irb(main):001:0> user = User.new(name: 'rails', sensitive: 'sensitive')
=> #<User id: nil, name: "rails", sensitive: [FILTERED], created_at: nil, updated_at: nil>

pp を実行した場合も [FILTERED] で表示されます。

irb(main):002:0> pp user
#<User:0x0000556be6e41c48
 id: nil,
 name: "rails",
 sensitive: [FILTERED],
 created_at: nil,
 updated_at: nil>
=> #<User id: nil, name: "rails", sensitive: [FILTERED], created_at: nil, updated_at: nil>

User model を編集する

filter_parameter_logging.rb から :sensitive を削除して、 user.rbfilter_attributes= メソッドを使います。

config/initializers/filter_parameter_logging.rb
Rails.application.config.filter_parameters += [:password]
app/models/user.rb
class User < ApplicationRecord
  self.filter_attributes += [:sensitive]
end

再度 irb で確認する

irb で User モデルを作成して、確認すると、 sensitive の値が [FILTERED] となっていることがわかります。

bash-4.4# bin/rails c
Running via Spring preloader in process 50
Loading development environment (Rails 6.0.0.rc1)
irb(main):001:0> user = User.new(name: 'rails', sensitive: 'sensitive')
=> #<User id: nil, name: "rails", sensitive: [FILTERED], created_at: nil, updated_at: nil>

pp を実行した場合も [FILTERED] で表示されます。

irb(main):002:0> pp user
#<User:0x0000556be6e41c48
 id: nil,
 name: "rails",
 sensitive: [FILTERED],
 created_at: nil,
 updated_at: nil>
=> #<User id: nil, name: "rails", sensitive: [FILTERED], created_at: nil, updated_at: nil>

filter_parameters で指定した場合と model の filter_attributes で指定した場合の違い

Rails.application.config.filter_parameters で指定した場合は、全てのモデルでその attribute が [FILTERED] で表示されます。( Rails.application.config.filter_attributes で設定されているものが、 filter_attributes に反映されます。)

filter_attributes で指定した場合は、指定した model の属性だけが [FILTERED] になります。

基本的には、 Rails.application.config.filter_parameters で指定した方が漏れがなくて良いと思います。

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try022_filter_parameters

追記

正規表現による attribute の指定も可能になってます( /sens/ を指定すると sensitive[FILTERED] になる)。

参考情報

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RSpecでlet(:foo)を再定義したい場合

RSpecを利用していて、let(:foo)fooの再定義がしたくなったときに少々困ったののまとめ

let再定義

letの再定義はRSpecではよく行うと思います。

RSpec.describe "Hoge.hoge" do
  subject { Hoge.hoge(foo) }

  let(:foo) { 100 }

  it { expect { subject }.not_to raise_error }

  context "when foo is not a number" do
    let(:foo) { "foo" }

    it { expect { subject }.to raise_error(ArgumentError) }
  end
end

let(:foo)で定義されている foo はまるで変数のように見える何かで、評価は it の実行時に行われます。

困る場合

外で定義したfooを利用してfooを再定義しようとすると困ります。

RSpec.describe "Hoge.hoge" do
  subject { Hoge.hoge(foo) }

  let(:foo) { 100 }

  it { expect { subject }.not_to raise_error }

  context "when foo is negative" do
    let(:foo) { foo * -1 }           # これ

    it { expect { subject }.to raise_error(ArgumentError) }
  end
end

これをやろうとすると、fooが再帰的に評価されて stack level too deep. と言われて死にます。

「そんなlet書くなよ」という話もあるのですが、こういうことをしたくなった理由は shared_examples でした。

shared_examples の例

strings_converter_spec.rb
RSpec.describe StringsConverter do
  let(:converter) { StringsConverter.new }
  let(:items) { ["rock", "paper", "scissor"] }
  subject { converter.run(items) }

  it_behaves_like "a strict-typed Converter"
end
integers_converter_spec.rb
RSpec.describe IntegersConverter do
  let(:converter) { IntegersConverter.new }
  let(:items) { [100, 200, 300] }
  subject { converter.run(items) }

  it_behaves_like "a strict-typed Converter"
end
strict_converter_behaviour.rb
RSpec.shared_examples "a strict-typed Converter" do
  describe "#run" do
    subject { converter.run(items) }

    it "is implemented" { expect { subject }.not_to raise_error(NotImplementedError) }

    context "when argument `items` include other types" do
      # ここでitemsを it_behaves_like 元の定義に基づいて再定義したい
      let(:items) { items + [nil] }

      it { expect { subject }.to raise_error(ArgumentError) }
    end
  end
end

ここでは各 Converter にわたす配列の要素の型は各specファイルで定義しつつ、共通のふるまいだけを切り出そうとしています。
処理する配列にnilが含まれている場合に ArgumentErrorraiseすることを、その直前でGreenになるような配列に最低限の改変(+ [nil])を行った場合を作成することでテストしようとしています。が、循環参照で死にます。

なぜダメなのか

contextdescribeはクラス定義を行っています。contextがネストされると、内側で定義されたcontextクラスは外側のものを継承します。
そして let() はおおよそ define_method() のエイリアスです。

describe "some Foo" do
  let(:name) { "hoge" }
  describe "when name is fuga"
    let(:name) { "fuga" }
  end
end

class SomeFoo
  define_method :name { "hoge" }
  class WhenNameIsFuga < SomeFoo
    define_method :name { "fuga" }
  end
end

っぽくなります。

つまり let(:foo) { foo } と書いてしまうと同じクラスの中で自分自身を最初に見つけるので、無限に再帰が起きることになります。
記述形式から期待するような foo = foo + 1 とは全く挙動が異なるのがポイントでした

どうすればいいのか

  • letが変数定義ではなく動的なメソッドである
  • it_behaves_like で最低でも一つ間にクラス生成を挟んでいて、外側を継承している

つまり let の中で外側のcontextのものを参照するためには super が使えるということになります。

strict_converter_behaviour.rb
RSpec.shared_examples "a strict-typed Converter" do
  describe "#run" do
    subject { converter.run(items) }

    it "is implemented" { expect { subject }.not_to raise_error(NotImplementedError) }

    context "when argument `items` include other types" do
      # super を呼んで定義済み配列GET~!
      let(:items) { super + [nil] }

      it { expect { subject }.to raise_error(ArgumentError) }
    end
  end
end

と思いきや、今度は

implicit argument passing of super from method defined by
  define_method() is not supported. Specify all arguments explicitly.

などと怒られます。define_method 内でsuperする場合は明示的にarityを指定する必要があるので、 super() にして解決です。

    context "when argument `items` include other types" do
      # super() で引数がないことを示す
      let(:items) { super() + [nil] }

      it { expect { subject }.to raise_error(ArgumentError) }
    end

まとめ

  • letdefine_method
  • describe expect はクラス定義
  • describeの内外は継承の関係
  • 内側の define_method から外側の define_method を利用するには superを使えばいい

    • super には引数明示が必要
    • 引数なしなら super()
  • そんなコードを書かない

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】配列を操作するメソッドをまとめてみた

ary.each_slice(N) #配列を任意の要素数の配列に分割

配列から奇数、偶数番目の要素を取り出す

odd = ary.each_slice(2).map(&:first)
even = ary.each_slice(2).map(&:last)

https://qiita.com/ddgg7755/items/ed7db4b342b783620b41

要素の削除

参考:https://uxmilk.jp/24060

delete

配列の要素を削除する。

a = [1, 2, 2, 3, 3, 3]
a.delete(2)
print a # [1, 3, 3, 3]

delete_at

指定位置の要素を削除

a = ["a", "b", "c", "d", "e"]
a.delete_at(3)
print a # ["a", "b", "d", "e"]

slice!

配列から指定範囲の要素を削除する
配列.slice!(削除開始位置, 削除する長さ)

a = ["a", "b", "c", "d", "e"]
a.slice!(1, 3)
print a # ["a", "e"]

要素の取り出す

firstとlast

firstは最初の要素、lastは最後の要素を配列から取り出す。
https://qiita.com/wai-doi/items/6aed16ad4bbaeb446c7f

arr = [0, 1, 2, 3, 4]
arr.first #=> 0
arr.last  #=> 4

[]との違いは?

&:メソッド名表記を使えるので、mapメソッドをシンプルに書ける。
また、レシーバがnilの場合は&.でエラーを回避できます。

nil[0]     #=> NoMethodError: undefined method `[]' for nil:NilClass
nil.first  #=> NoMethodError: undefined method `first' for nil:NilClass
nil&.first #=> nil

条件を満たす要素を取り出すor削除

https://mickey24.hatenablog.com/entry/20110227/ruby_array_select_reject_partition

select (select!)

ブロック内の評価がTRUEになる要素を配列で返す

a = [1, 3, 4, 7, 9, 13]
a.select{|e| e % 3 == 0} #=> [3, 9]

reject (reject!)

ブロックの評価結果がTRUEとなる要素を除いた配列を返す

a = [1, 3, 4, 7, 9, 13]
a.reject{|e| e % 3 == 0} #=> [1, 4, 7, 13]

partition

ブロック内の評価がTRUE、FALSEになる要素で分けて、配列を返す。

a = [1, 3, 4, 7, 9, 13]
a.partition{|e| e % 3 == 0} #=> [[3, 9], [1, 4, 7, 13]]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む