20190323のRubyに関する記事は13件です。

current_userの↓説明できる?

これって元々どうなってたの?

app/helpers/sessions_helper.rb
def current_user
    @current_user ||= User.find_by(id: session[:user_id])
end

っていうかこれどう動いてたんだっけ?

Lv.1 if文

if @current_user.nil?
  @current_user =  User.find_by(id: session[:user_id])
else
  @current_user =  @current_user
end

Lv1.1 asmさんからご提案頂きました。

@current_user = if @current_user.nil?
                  User.find_by(id: session[:user_id])
                else
                  @current_user
                end

「移り変わり」感がよりイメージしやすくなりましたね。

Lv.2 三項演算子

名前でビビりますね。

@current_user = @current_user.nil? ? User.find_by(id: session[:user_id]) : @current_user

これにリファクタリングできたらかっこいいけど…

Lv.3 or 演算子 「 || 」

@current_user = @current_user || User.find_by(id: session[:user_id])
                 ②  ①

@current_userが無ければ(nil)なら、User-を代入
②userと||のスキマ
 @current_userが存在すれば、@current_userの値はそのまま。

Lv3.5 大前提

n = n + 1
n += 1

同じ意味でしたね。

Lv.4 自己代入演算子 「||=」

@current_user ||= User.find_by(id: session[:user_id])
           ①

①Lv.3.5の
 nが@current_userの立場

まとめ

いきなりif文から「||=」までは難しい。
条件によりけりですが、Lv.2までは大体リファクタリングできる。
今回がかなり特別。

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

Ruby on Rails DM 2019 登壇者の影響を受けた3冊まとめ (day.2)

すごいRailsエンジニアの方々がどんな書籍を読んで今に至るのか、またどんな本が人気なのか?をもとに、もっと高みを目指そうということで、Ruby on Rails 2019の冊子で紹介された、

「影響を受けた3冊」

をリスト形式で掲載。途中で力尽きて、著作名のみになっている点はご了承ください。

イベントについて:
Ruby on Rails 2019 3/22~23 開催
https://techplay.jp/event/714867

Day 1の登壇者の方々 はこちら

https://qiita.com/shogotgm/items/adece25dd5ac16fcb7cf

Day 2の登壇者の影響を受けた3冊まとめ

@ moro

・UNIXという考え方-その設計思想と哲学
・テスト駆動開発入門
・エクストリームプログラミング

@ taiki-t

・オブジェクト指向設計 実践ガイド Rubyでわかる進化しつづける柔軟なアプリケーションの育て方
・イシューからはじめよ -知的生産のシンプルな本質
・Rails Tutorial

@ masa-iwasaki

・達人プログラマー 職人から名匠への道
・ライト、ついてますか -問題発見の人間学
・OSの基礎と応用 - 設計から実装、DOSから分散OS Amoebaまで

@ willnet

・ウェブ進化論 本当の大変化はこれから始まる
・RailsによるアジャイルWebアプリケーション開発
・パーフェクトRuby on Rails

@ fujimura

・RailsによるアジャイルWebアプリケーション開発
・The Little Schemer
・言語哲学大全

@ kokuyouwind

・マッチ箱の脳(AI)-使える人工知能のお話
・プログラムはなぜ動くのか 知っておきたいプログラムの基礎知識
・数学ガール

@ koichiroo

・入門 GNU Emacs
・JavaからRubyへ
・達人プログラマー 職人から名匠への道

@ idesaku

・達人プログラマー 職人から名匠への道
・アジャイルな見積もりと計画づくり ~ 価値あるソフトウェアを育てる概念と技法 ~
・ライト、ついてますか - 問題発見の人間学

@ koic

・オブジェクト指向スクリプト言語 Ruby
・達人プログラマー 職人から名匠への道
・エクストリームプログラミング

@ radioboo

・初めてのPerl
・アジャイルソフトウェア開発の奥義
・ねぼけ人生

@ risacan

・Practical Object-Oriented Design in Ruby
・プログラムはなぜ動くのか 知っておきたいプログラムの基礎知識
・Namluby pana Pipi

@ joker1007

・ジョジョの奇妙な冒険
・アジャイルサムライ - 達人開発者への道
・パーフェクト Ruby

@ f440

・Agile Web Developmet with Rails
・エンタープライズ Rails
・ウェブオペレーション - サイト運用管理の実践テクニック

@ yoshuki

・コンサルタントの秘密 - 技術アドバイスの人間学
・ハッカーと画家 コンピュータ時代の創造者たち
・Ruby on Rails 携帯サイト開発技法

@ unak

・闘うプログラマー
・プログラミング技法
・達人プログラマー 職人から名匠への道

@ ikedaosushi

・イシューからはじめよ - 知的生産のシンプルな本質
・CAREER SKILLS ソフトウェア開発者の完全キャリアガイド
・ハッカーと画家、コンピュータ時代の創造者たち

@ komagata

・プログラミングPerl
・ピープルウエア
・人月の神話

@ bany

・Rubyist Magazin 出張版 正しいRubyコードの書き方講座
・JavaScript The Good Parts
・UNIXという考え方 -その設計思想と哲学

@ shinamon129

・Flash&ActionScript3.0 プロが教える本当の使い方
・ツイッターで学んだいちばん大切なこと
・エラスティックリーダーシップ 自己組織化チームの育て方

@ yasaichi

・テスト駆動開発
・ハッカーと画家、コンピュータ時代の創造者たち
・問題発見プロフェッショナル

@ knu

・アスキー「256倍使うための本」
・プログラミングPerl
・C言語による標準アルゴリズム事典

@ mtsmfm

・メタプログラミングRuby
・アジャイルサムライ - 達人開発者への道
・Rails によるアジャイルWebアプリケーション開発

@ pipopotamasu

・開眼!JavaScript - 言語仕様から学ぶJavaScriptの本質
・やさしいJAVA
・アメリカの少年野球 こんなに日本と違ってた

@ hokaccha

・ユニバーサルHTML/XHTML
・ハイパフォーマンス Webサイト -高速サイトを実現する14のルール
・初めてのRuby

@ hanachin

・ハッカーと画家 コンピュータ時代の創業者たち
・情熱プログラマー ソフトウェア開発者の幸せな生き方
・フリーソフトウェアと自由な社会

@ katsumata-ryo

・たのしいRuby
・SCRUM BOOT CAMP THE BOOK
・落下する夕方

@ k0kubun

・たのしいC
・たのしいRuby
・きつねさんでもわかる LLVM

@ 284km

・ジョジョの奇妙な冒険 Part5 黄金の風
・ジョジョの奇妙な冒険 Part3 スターダストクルセイダース
・ジョジョの奇妙な冒険 Part7 スティール・ボール・ラン

@ sinsoku

・JAVA言語で学ぶデザインパターン入門
・アジャイルソフトウェア開発の奥義 オブジェクト指向開発の真髄と匠の技
・レガシーコード改善ガイド

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

Ruby on Rails DM 2019 登壇者の影響を受けた3冊まとめ (day.1)

概要

すごいRailsエンジニアの方々がどんな書籍を読んで今に至るのか、またどんな本が人気なのか?をもとに、もっと高みを目指そうということで、Ruby on Rails 2019の冊子で紹介された、

「影響を受けた3冊」

をリスト形式で掲載。途中で力尽きて、著作名のみになっている点はご了承ください。

イベントについて:
Ruby on Rails 2019 3/22~23 開催
https://techplay.jp/event/714867

Day 2の登壇者の方々 はこちら

https://qiita.com/shogotgm/items/f074fe85c285e02a2027

Day 1の登壇者の影響を受けた3冊まとめ

@ dhh

・The Manual: A Philosopher's Guide to Life (Epictetus, Sam Torode)
・Escape from Freedom (Erich Fromm)
・Punished by Rewards (Alife Kohn)

@ takahashim

・ひとめあなたに… (新井 素子)
・心のなかの冷たい何か (若竹 七海)
・計算機プログラムの構造と解釈 (Gerald Jay Sussman, Julie Sussman, Harold Abelson)

@ jeremy

・How to Solve It (George Poyla)
・Calvin and Hobbes (Bill Watterson)
・The Overcoat (Nikolai Gogol)

@ onk

・影響力の武器 (ロバート・B・チャルディーニ)
・バクマン。 (大場 つぐみ・小畑 健)
・大東京トイボックス (うめ)

@ youchan

・あすなろ物語 (井上 靖)
・路上 (ジャック・ケルアック)
・聖書

@ kei-p, @ gotchane

・UNIX という考え方 (Mike Gancarz)
・プログラマが知るべき 97のこと (和田 卓人)
・リーダブルコード (Dustin Boswell)

@ yoshinori

・プログラマの数学 (結城 浩)
・情熱プログラマー (Chad Fowler)
・テスト駆動開発 (Kent Beck)

@ yahonda

・Head First Rails(David Griffiths)
・遠い太鼓 (村上 春樹)
・Oracle Database 概要 (Oracle Docs)

@ tawachan

・限界費用ゼロ社会 (ジェレミー・リフキン)
・社会契約論 (J.J ルソー)
・ブロックチェーンアプリケーション開発の教科書 (篠原航、 加嵜長門)

@ hsbt

・Rubyのしくみ (Pat Shaughnessy)
・Crafting Rails Applications (Jose Valim)
・アジャイルサムライ (Jonathan Rasmusson)

@ upinetree

・アジャイルサムライ (Jonathan Tasmusson)
・たのしい開発 スタートアップRuby (大場寧子、大場光一郎、他)
・リーダブルコード (Dustin Boswell)

@ itkrt2y

・Simple is not easy
・TOYOTA KATA
・Ruby on Rails Tutorial

@ rust

・四次元の世界 - 超時空から相対性理論へ (都筑 卓司)
・はじめの一歩を踏み出そう - 成功する人たちの起業術 (マイケル・E・ガーバー)
・逆境ナイン (島本 和彦)

@ yancya

・たのしい Ruby (高橋 征義、後藤 裕蔵)
・SQL アンチパターン (Bill Karwin)
・CPUの創りかた (渡波 郁)

@ m-nakamura145

・マスタリング TCP/IP 入門編
・やさしい C++
・珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造

@ mrkn

・C言語による最新アルゴリズム事典 (奥村 靖彦)
・プログラミング言語 C++ (Bjarne Stroustrup)
・ご冗談でしょう ファインマンさん (Richard P. Feynman)

@ takatoshi-maeda

・メタプログラミング Ruby (Paolo Perrotta)
・イシューからはじめよ (安宅 和人)
・リーン・スタートアップ (Eric Ries)

===(ここからは著作名のみです...)===

@ riho

・夜と霧
・オブジェクト指向でなぜつくるのか
・ライト、ついてますか - 問題発見の人間学

@ nay

・Effective Java
・RailsによるアジャイルWebアプリケーション開発
・アドラー心理学入門

@ takkanm

・たのしいRuby
・情熱プログラマー ソフトウェア開発者の幸せな生き方
・Clean Coder プロフェッショナルプログラマへの道

@ ota42y

・情熱プログラマー ソフトウェア開発者の幸せな生き方
・理科系の作文技術
・ゲーデル、エッシャー、バッハーあるいは不思議の環

@ ujihisa

・UNIXという考え方 - その設計思想と哲学
・発酵の技法 - 世界の発酵食品と発酵文化の探求
・How to Become A Hacker

@ owlworks

・UNIXという考え方 - その設計思想と哲学
・予想どおりに不合理: 行動経済学が明かす「あなたがそれを選ぶわけ」
・ザ・ゴール - 企業の究極の目的とは何か

@ katorie

・初めてのプログラミング
・Webを支える技術 - HTTP, URI, HTML, そしてREST
・パターン、Wiki、XP ~ 時を超えた創造の原則~

@ yui-knk

・Ruby ソースコードで完全解説
・はじめての OSコードリーディング
・ディジタル回路設計とコンピュータアーキテクチャ ARM版

@ aeroastro

・人工衛星の力学と制御ハンドブック - 基礎理論から応用技術まで
・詳解 Linuxカーネル
・Goならわかるシステムプログラミング

@ taogawa

・リファクタリング - プログラムの体質改善テクニック
・Java言語で学ぶデザインパターン
・山椒魚戦争

@ kyuden

・パーナムピアノ教本シリーズ

@ r7kamura

・初めてのPerl
・初めてのRuby
・Patterns of Enterprise Application Architecture

@ Morred

・Practical Object-Oriented Design in Ruby: An Agile Primer
・Letters from a Stoic
・Pippi Longstocking

@ amatsuda

・Rails3 レシピブック 190の技
・HEAD FIRST RAILS
・たのしいRuby

@ emorima

・プログラミング言語 C
・深い河
・はみだしっ子

@ siman-man

・たのしいRuby
・プログラミングコンテストチャレンジングブック
・メタプログラミング Ruby

雑なまとめ:「たのしいRuby」はいい本

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

App Store Connect APIからアプリの売上情報を取り出して、slackに投げるプログラムを作ってみた。

環境

MacOS Mojave(10.14.3)
Ruby 2.5.1
rails 5.2.2
rails apiモードでフォルダ作成済み

手順

0.必要なGemをインストール

Gemfile
gem 'slack-api'
gem 'jwt'
gem 'httparty', '~> 0.13.7'
gem 'zlib', '~> 0.1.0'
$ bundle install

1.AppStoreConnectからアプリの情報を入手する

1-1.キー情報を発行し、PRIVATE KEYファイルをlibフォルダ下に配置

以下の記事の通りに、キー情報(Issuer ID、キーID、PRIVATE KEY)を取得します。
https://qiita.com/kurikazu/items/135a791ba09121d7a534
ダウンロードしたPRIVATE KEYファイル(ファイル名.p8)はlibフォルダに配置します。

1-2.トークンを発行し、変数に格納

Appleが提供しているAPIの叩き方です。
requireしているものは後で必要になるので、先に記述しておきます。

application_controller.rb
class ApplicationController < ActionController::API
require 'httparty'
#API用
require 'base64'
require 'jwt'
#gzip解凍用
require 'zlib'
require 'stringio'

$now = DateTime.now
  def iOS
      issure_id = '[Issuer ID]欄に表示された文字列'
      key_id = '[キーID]欄に表示された文字列'
      private_key = OpenSSL::PKey.read(File.read(Rails.root.to_s + "/lib/ダウンロードしたPRIVATE KEYファイル名"))

      $token = JWT.encode(
        {
          iss: issure_id,
          exp: Time.now.to_i + 20 * 60,  # トークンの有効期限は20分以内とAppleが規定している
          aud: 'appstoreconnect-v1'      # audは appstoreconnect-v1 固定
        },
        private_key,
        'ES256', # 署名方式は ES256 固定
        header_fields = {
          kid: key_id
        }
      )
  end
end

1-3.Httpartyを使ってAPIを叩く

application_controller.rb
class ApplicationController < ActionController::API

  〜省略〜

  response = HTTParty.get 'https://api.appstoreconnect.apple.com/v1/salesReports', headers:{"Accept" => "application/a-gzip", :Authorization => "Bearer #{$token}"}, :query => {"filter[frequency]": "DAILY", "filter[reportDate]": $now.strftime('%Y-%m-%d'), "filter[reportSubType]" => "SUMMARY", "filter[reportType]" => "SALES", "filter[vendorNumber]" => "ベンダー番号"}

Queryパラメータの詳細はこちら
https://developer.apple.com/documentation/appstoreconnectapi/download_sales_and_trends_reports

1-4.gzファイルを解凍し、変数に格納

application_controller.rb
class ApplicationController < ActionController::API

  〜省略〜

   gz = Zlib::GzipReader.new(StringIO.new(response.body.to_s))
   data = gz.read
  end
end

これで、"data"にファイルが格納されました。

2.Slackのトークンを作成する

2-1.以下のサイトで、トークンを作成

https://api.slack.com/custom-integrations/legacy-tokens
"create token"を押すと、tokenカラムにそのルームのtokenが表示されます。
スクリーンショット 2019-03-23 14.50.13.jpg

2-2.config/initializersフォルダにファイルを作成

config/initializers/slack_api.rb
require "slack"

Slack.configure do |config|
  config.token = "取得したトークン"
end

2-3.Slack APIを使ってテキストを送信

application_controller.rb
class ApplicationController < ActionController::API

  〜省略〜

  Slack.chat_postMessage(text: data, username: '任意のユーザーネーム', channel: '#チャンネル名')
end

テキストメッセージ欄に先ほどの変数"data"を入れ、完成です。

全体像

application_controller.rb
class ApplicationController < ActionController::API
require 'httparty'
#API用
require 'base64'
require 'jwt'
#gzip解凍用
require 'zlib'
require 'stringio'

$now = DateTime.now
  def iOS
      issure_id = '[Issuer ID]欄に表示された文字列'
      key_id = '[キーID]欄に表示された文字列'
      private_key = OpenSSL::PKey.read(File.read(Rails.root.to_s + "/lib/ダウンロードしたPRIVATE KEYファイル名"))

      $token = JWT.encode(
        {
          iss: issure_id,
          exp: Time.now.to_i + 20 * 60,  # トークンの有効期限は20分以内とAppleが規定している
          aud: 'appstoreconnect-v1'      # audは appstoreconnect-v1 固定
        },
        private_key,
        'ES256', # 署名方式は ES256 固定
        header_fields = {
          kid: key_id
        }
      )

   response = HTTParty.get 'https://api.appstoreconnect.apple.com/v1/salesReports', headers:{"Accept" => "application/a-gzip", :Authorization => "Bearer #{$token}"}, :query => {"filter[frequency]": "DAILY", "filter[reportDate]": $now.strftime('%Y-%m-%d'), "filter[reportSubType]" => "SUMMARY", "filter[reportType]" => "SALES", "filter[vendorNumber]" => "ベンダー番号"}
   gz = Zlib::GzipReader.new(StringIO.new(response.body.to_s))
   data = gz.read

   Slack.chat_postMessage(text: data, username: '任意のユーザーネーム', channel: '#チャンネル名')
  end
end

※ベンダーIDはiTunes connectの"売上とトレンド"で確認できます!

参考

Generating JWT Tokens for App Store Connect API
AppStoreConnect API 公式サイト/Download Sales and Trends Reports
App Store Connect APIを利用してアプリ情報を取得する
Slack APIのTokenの取得・場所
Rails slack連携をしてみた
How to decompress Gzip string in ruby?

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

[Homebrew] cannot load such fileなどのエラーの対処法

Homebrew を久しぶりに使おうとしたら以下のようなエラーが発生したのでメモ。

$ brew --help
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- active_support/core_ext/object/blank (LoadError)
    from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/local/Homebrew/Library/Homebrew/global.rb:10:in `<top (required)>'
    from /usr/local/Homebrew/Library/Homebrew/brew.rb:21:in `require_relative'
    from /usr/local/Homebrew/Library/Homebrew/brew.rb:21:in `<main>'

brew style を実行するも変わらず。
(https://stackoverflow.com/questions/54888582/ruby-cannot-load-such-file-active-support-core-ext-object-blank)

また、sudo chown -R $(whoami):admin /usr/local は権限がないと言われ、

$ sudo chown -R $(whoami):admin /usr/local
chown: /usr/local: Operation not permitted

sudo chown -R $(whoami) $(brew --prefix)/* を実行するも変わらず。
(https://qiita.com/k-hotta/items/7236f68ef26f7771b02f)

対処法

公式サイトのコマンドから再インストールすると解決した。
https://brew.sh/index_ja

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

今からRailsを触る人が出くわすエラー集(2019/3)

タイトルの通りです。

sqlite3 1.4.0

2019/2の時点ではRailsがsqlite3の1.4.0は対応していないらしく、nativeなんたらが「インストールできません」みたいなエラーが発生します。

解決策

Rails sで作ったアプリの中のgemfileで、古いバージョンのsqlite3を指定する。


gem 'sqlite3'

gem 'sqlite3', "1.3.13"
に変更

rails2.6.1とbundler2

rails2.6.1はbundlerの古いバージョンを固定で使用するような仕様になっているらしく、エラーが発生することがあります。

解決策

rbenvを使って、古いバージョンのrubyを指定する。

他のエラーやもっといい解決策等あれば教えてください。

参考リンク
https://ja.stackoverflow.com/questions/52689/ruby-2-6-1-rails-%E3%81%A7-you-must-use-bundler-2-or-greater-with-this-lockfile-%E3%81%8C%E3%81%A7%E3%81%BE%E3%81%99

https://qiita.com/_am_/items/c1dbeb11f40bbbac8fd9

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

【Rails】サーバ起動+αの手順

開発環境

windows wsl(Debian GNU/Linux 9)

DB構築(Ubuntu)

sudo apt install mysql-server mysql-client -y
sudo apt install default-libmysqlclient-dev -y
sudo mysql_secure_installation

sudoつけないと権限エラーになる問題を解決する方法

drop user 'root'@'localhost';
create user 'root'@'%' identified by 'root';
grant all privileges on *.* to 'root'@'%' with grant option;
flush privileges;

プロジェクト構築

プロジェクト作成
rails new todoapp -d mysql

初回のみbundleのインストールは--pathオプションを付ける
次回以降は.bundleが作成されるため--pathオプションは不要である。
bundle install --path vendor/bundle

以下のエラーが出たので
An error occurred while installing mysql2 (0.5.2), and Bundler cannot
continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'`
succeeds before bundling.

エラーログに従う。
gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/

HTMLテンプレートエンジンをEBRからSLIMへ変更
Genfileに以下を追記する。
gem 'slim-rails'
gem 'html2slim'

gemを更新したのでbandleを更新する。
bundle install

ERBをslimへ変換後、ERBを削除。
bundle exec erb2slim app/views/layouts/ --delete

SCSSを用いる設定に変更
(cssフレームワークを使う必要ない方は無視してください)
.\app\assets\stylesheets\配下の
application.cssを削除しapplication.scssを作成。

DBを作成
bin/rails db:create

サーバ起動動作確認
bin/rail s

model作成

bin/rails g model [モデル名] [属性名:データ型 ...]
bin/rails g model Task name:String description:text

モデルの自動生成での成果物表

成果物 パス 説明
モデルクラス app/models/task.rb タスククラス
マイグレーションファイル db/migration/現在日時_create_tasks.rb DBへの変更を行う
自動テスト test/models/task_test.rb 自動テストを行う
自動テストを行うfixture test/fixture/task.yml 自動テストに使用するテストデータの投入定義

mysqlとrailsのデータ型mapping参考サイト

controller/view作成

bin/rails g controller コントローラー名 [アクション名 ...][オプション]
bin/rails g controller task index show new edit
 
アクション一覧
indexshowneweditcreateupdatedestroy

すべてのアクションに対してルーティングを行うことができる記述。
taskに関するルーティング記述を削除し、以下を記述する。
記載場所:config/routes.rb
resources :task

ルートパス(http://localhost:3000)にアクセスしたした時のルーティング設定
記載場所:config/routes.rb
root to: 'task#index'

詳しく記載しているサイト

サーバ起動動作してindexが表示されれば成功。
bin/rail s

追記

ルーティングのパスがバージョンによって違う?
エラーが出るときは以下で確認して設定する。
/bin/rails routes

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

fluentdのconfig(input/output)

とある機会でfluentdを触ることがあったので気を付けておくべきconfigに関しての備忘録
公式ドキュメントを読めばわかるけど、すべて英語なのと自分の気がついたことをまとめるために記載します。(随時更新)

topic

主に下記の内容が対象。
filterプラグインに関しては、用途によりそれぞれなので記載しません。
また、tagなどの基本的なflunetdに対する知識が前提。
主に、input/outputで必要そうなものに絞って記載します

記載時の対象バージョンは

. fluentd (version 1.2.2)
. ruby (2.5)

  • input
    • in_tailプラグイン
    • in_forwardプラグイン
  • output
    • out_fileプラグイン

INPUTプラグイン

主にflunetdに対してのデータ入力部分を受け持つ。
ここでデータを受け取り、input→filter→outputの順番でデータの受け渡しが行われる。(ざっくり説明)

in_tailプラグイン

主にファイルの読み込みに利用されるプラグイン
Linuxのtail -Fとほとんど同じ動作となる。

指定したファイルをtail -Fした際に標準出力に表示される内容をfluentdが入力として受け取ることができる。
注意点としては、tail -Fと同じ動きなので、読み込みは改行単位で区切られて読み込まれる。
読み込みファイルが壊れて最終行が改行コードで終わっていない場合、その内容はflunetdで読み込まれない。
(multiline設定でmultiline_flush_intervalを利用する場合を除く)

tag

tag設定。
対象ファイル読み込み時のtagを設定する。
後述するpathに複数のファイルパスを記載した場合は、その全てに対して同じtagが付与される。(placeholderを利用しない場合)

path

読み込み対象のファイルパス指定。
複数のファイルを指定できる。指定する際はカンマ区切り
また、ワイルドカード等の使用が可能。

pos_file

in_tailプラグインを使う場合は殆ど必須の設定
読み込み対象のファイルのinodeと読み込み行の情報を保存するファイルパスを指定する。
この設定を指定することで、読み込み対象ファイルをどこまで読み込んでいたかの情報が保存されるため、fluentdが再開された場合に最後に読み込まれた行から再度取り込みを再開することができる。

ファイル名に対して1行で情報が保持されるため、pathでワイルドカード等を利用して可変ファイル名のファイルを読み込んでいる場合、posファイルへの記載内容は徐々に増えていく。
読み込みが終了した(対象のファイルがなくなった)際のposファイルの情報の整理はfluentdの再開を契機に行われるため、fluentdが連続動作している限りposファイルの容量は増えていく(v1.2.2時)

read_from_head

fluentd起動時に読み込み対象ファイルを先頭行から読み込む設定。
pos_fileの設定で対象ファイルの情報がある場合は、最終読み込み行からの読み込みが優先される。
初回読み込み時にデータの取りこぼしを防ぐための設定。

rotate_wait

読み込み対象ファイルがlogrotateなどによりローテートした際に、一つ古いファイルへの更新が同時発生している場合に、どのくらいそのファイルの読み込みを継続するかの設定。

例えば、/var/log/messagesがlogrotateにより/var/log/messages.1にローテートされた際にrotate_waitを3sに設定していると、ローテート後3秒間は/var/log/messages.1への書き込み内容も取り込むことができる。

encode,from_encode

読み込み時のencode設定(encode)とin_tailプラグイン処理後のencode設定(from_encode)

path_key

指定した文字列のフィールド名で読み込み対象ファイルパスの情報を保持することができる。
読み込み対象ファイルのフルパスをデータとして保持する際に設定する。

in_forwardプラグイン

主にfluent-catコマンドからの入力や後述するout_fowardプラグインからのデータ入力を受け取る際に利用する。
fluentd - fluentd間のデータ受け取りに使われることが多い。

port

listenするport番号

bind

bindするIPの設定
ここでデータ受け取りを行うIPの制限を行うことができる。

OUTPUTプラグイン

主にfluentdからデータのOUTPUTを行う際に利用するプラグイン

out_fileプラグイン

fluentdからファイル出力を行う際に使用する。

path

出力ファイルパスの設定。
固定ファイル名での出力も可能だし、tag等のplaceholderを利用して可変ファイル名とすることも可能
placeholderに関しては下記を参照
https://docs.fluentd.org/v1.0/articles/buffer-section#sts=Placeholders

append

false設定にすると出力ファイル名の末尾に_0,_1等の数字が付与され分割される。
分割単位はchunkごとに分割されるため、通常はtrueにして運用する。

path_suffix

pathで設定したファイル名の末尾に付与する文字列を設定する。
後述するadd_path_suffixの設定により付与しないことも可能。
前述のappendにより付与される数字はこの文字列のあとに付与される。

add_path_suffix

前述のpath_suffixの末尾に付与するかどうかの設定。
pathで設定した内容のままのファイル名で出力したい場合は、本設定をfalseにする必要あり。

参考ドキュメント
https://docs.fluentd.org/v1.0/articles/quickstart

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

truffleruby のマイクロベンチマーク

先日。
何の気なしに

rbenv install -l

としてみたら、下の方に truffleruby-1.0.0-rc14 などの見慣れない文字が。

なんだろうと思ってぐぐってみたら

A high performance implementation of the Ruby programming language. Built on the GraalVM by Oracle Labs.
( https://github.com/oracle/truffleruby )

とのこと。本当に速いの? と思って今日も楽しいマイクロベンチマーク。

走らせたコード

走らせたのはこんなコード:

fobo.rb
# frozen_string_literal: true

def fibo(n)
  if n<=1
    1
  else
    fibo(n-1)+fibo(n-2)
  end
end

p fibo(ARGV[0].to_i)

測るコード

こいつを走らせて集計するスクリプトはこんな感じ:

bench.rb
# frozen_string_literal: true

require "json"

ENVS = [
  [ '2.6.2' ],
  [ '2.6.2', '--jit' ],
  [ 'jruby-9.2.6.0' ],
  [ 'truffleruby-1.0.0-rc14' ],
]

def rbenv(v)
  path = `RBENV_VERSION='#{v}' rbenv which ruby`.rstrip
  yield(path)
end

data = ENVS.each.with_object(Hash.new{ |h,k| h[k]={} }) do |(e,opt),o|
  name = [e,opt].compact.join("/")
  opt ||= ""
  (28..42).each do |n|
    rbenv(e) do |ruby|
      tick = /real\s+(\d+m[\d\.]+s)/.match(%x[(time "#{ruby}" #{opt} fibo.rb #{n}) 2>&1])[1]
      o[name][n]=tick
      $stderr.puts( [name, n, tick].join(" ") )
    end
  end
end

puts( JSON.pretty_generate(data))

出走者は

  • CRuby 2.6.2 ( 通常 )
  • CRuby 2.6.2 ( --jit )
  • jruby-9.2.6.0
  • truffleruby-1.0.0-rc14

の四名。

ビジュアライズするコード

出てきた JSON を以下のスクリプトでグラフにする:

julia
using Plots
using JSON

jstxt = open("result.json") do file
  read(file, String)
end

data = JSON.parse(jstxt)

function to_sec(x)
  strm,strs = split(x, "m")
  m=parse(Float64,strm)
  s=parse(Float64,strs[1:length(strs)-1])
  m*60+s
end

envs = [ "2.6.2", "2.6.2/--jit", "jruby-9.2.6.0", "truffleruby-1.0.0-rc14" ]
k = sort(collect(keys(data[envs[1]])))
println(k)
y = map( env->begin
  values = map( x->data[env][x], k )
  return map( to_sec, values )
end, envs )

plot( y,
  legend = :topleft,
  label = envs,
  xlabel = "Argument of fibo",
  ylabel = "result of time (real)",
  xticks = (1:length(k), k),
  yscale=:log10
)

savefig("plot.pdf")

このスクリプト。実行するのに 20秒以上かかる。なんでだろ。

まあそれはいいとして。
できたグラフは下図。

image.png

truffleruby は全領域で JRuby に勝っている。
起動時間がやや遅いが、計算量が多くなると CRuby や CRuby+JIT を抜いて一位になる。
なるほど速い。

しかし、まだ release candidate なので困ることもあると思う。

オフラインリアルタイムどう書くのような遊びでは役に立つと思うけどどうだろう(次回=最終回?の問題が計算量が気になる問題とは限らないけどね)

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

prettier-ruby VSCode Formatter設定

@koshi_life です。

Prettierがイケてるという話だったので、Ruby版の prettier-ruby をVSCode上でRubyファイルを保存時に自動でフォーマットされるように設定してみました。

output800-5.gif

VSCode上の設定

STEP1. Prettier拡張をインストール

VSCodeprettier-vscode という拡張をインストールします。

STEP2. Ruby用のプラグインをインストール

prettier-ruby VSCode formatOnSave を参考にしました。

STEP1で導入した拡張がインストールされているディレクトリに移動してRuby用のプラグインをインストールします。

$ cd ~/.vscode/extensions/esbenp.prettier-vscode-1.8.1/
$ npm install @prettier/plugin-ruby

※ Version部分は読み替えたほうが良いかもしれません。

STEP3. VSCodeの settings.json に加筆

  • settings.json に以下、Rubyファイル保存時にフォーマッターをかける設定を加筆。
    "[ruby]": {
        "editor.formatOnSave": true
    },
  • 参考キャプチャ: settings.json 開くまで
    • Preferences -> Settings
      vscode1.png
    • { } 選択
      vscode2a.png
    • settings.json 修正
      vscode3a.png

細かい設定

README.md#configuration 参照。

一括でFormatしたい場合はコマンドラインが楽

コマンドラインのインストール

README.md に書いてある package.json ある前提で以下でインストール。

# npm の場合
$ npm install --save-dev prettier @prettier/plugin-ruby

# yarnの場合
$ yarn add --dev prettier @prettier/plugin-ruby

使い方

# README.md より
$ ./node_modules/.bin/prettier --write path/to/file.rb

# 例: hoge.rb に適用
$ ./node_modules/.bin/prettier --write hoge.rb 
hoge.rb 612ms

# 例: appディレクトリ以下のRubyファイルに一括適用
$ find app -name *.rb | xargs node_modules/.bin/prettier --write
app/models/a.rb 311ms
app/models/b.rb 292ms
app/models/c.rb 342ms
app/models/d.rb 287ms
app/models/e.rb 229ms
...

参考

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

Stripeで定額制マーケットプレイスを実装する(rails)

名称未設定.001.jpeg

オンラインサロンや、月額駐車場のような定額制のマーケットプレイスを実装します。
前回、「RailsでStripe Connectを使ってみた」を投稿したのですが、この定額制の場合、そこにあるようなConnectだけでは一筋縄にいかないということが分かりました。定額制を採用するためには、「Stripe Billing」を別途で実装する必要があるため、StripeのGUIをそのまま使えるStandardアカウントでは実装できず、Customアカウントを使う必要が出てきました。

これが意外と厄介で、決済の責任がプラットフォーム側に依存されるようになるため、利用規約やセキュリティ面など気をつけなければならないことがたくさん出てきます。

決済〜入金までの流れ

  1. 決済フォームを作成する(Stripe Element)
  2. 本人確認フォームを作成する
  3. 銀行口座フォームを作成する
  4. 定額商品を作成する
  5. 顧客が定額商品を契約する
  6. プラットフォームからアカウントに送金される
  7. アカウントの口座に入金される

なかなか壮大なワークフローとなりました。
特に、7) プラットフォームからアカウントに送金される部分は想定しておらず、もっと簡単に実装できるかと思っていましたが、Webhookを使う必要があると分かりました。
個人的に、Webhookを使うのは初めてだったので、これはスタックしそうと構えていましたがngrockという便利ツールのおかげでスムーズに進みました。

決済フォームを作成する(Stripe Element)

決済フォームを作成する際にはStripe Elementを使うのがおすすめです。
基本的にクレジットカード情報はサーバー側で持たないため、Stripeのカスタマートークンを受け取るカラムのみをユーザーに追加してあげとけば問題ありません。

payments/new.html.erb
<script src="https://js.stripe.com/v3/"></script>

<%= form_for(@user, html: {class:'add-card', id: 'payment-form'}) do |f| %>
  <div class="block">
    <%= f.hidden_field :stripe_temporary_token, id: 'stripe_temporary_token' %>
    <input type="hidden" name="token" />          
    <div class="group">
      <label>
        <span>クレジットカード番号</span>
        <div id="card-number-element" class="field"></div>
      </label>
      <label>
        <span>有効期限</span>
        <div id="card-expiry-element" class="field"></div>
      </label>
      <label>
        <span>CVC</span>
        <div id="card-cvc-element" class="field"></div>
      </label>
    </div>
    <button type="submit" class="btn btnSubmit" id="submit-card">Submit</button>
    <div class="outcome">
      <div class="error"></div>
      <div class="success"></div>
    </div>
  </div>
<% end %>

JS部分は下記のようになります。

elements.js
var stripe = Stripe(gon.stripe_key);
var elements = stripe.elements();

var style = {
  base: {
    iconColor: "#666EE8",
    color: "#31325F",
    lineHeight: "40px",
    fontWeight: 300,
    fontFamily: "Helvetica Neue",
    fontSize: "15px",

    "::placeholder": {
      color: "#CFD7E0"
    }
  }
};

var cardNumberElement = elements.create("cardNumber", {
  style: style
});
if (document.getElementById("card-number-element")) {
  cardNumberElement.mount("#card-number-element");
}

var cardExpiryElement = elements.create("cardExpiry", {
  style: style
});
if (document.getElementById("card-expiry-element")) {
  cardExpiryElement.mount("#card-expiry-element");
}

var cardCvcElement = elements.create("cardCvc", {
  style: style
});
if (document.getElementById("card-cvc-element")) {
  cardCvcElement.mount("#card-cvc-element");
}

function setOutcome(result) {
  console.log("result", result);

  var successElement = document.querySelector(".success");
  var errorElement = document.querySelector(".error");
  successElement.classList.remove("visible");
  errorElement.classList.remove("visible");

  if (result.token) {
    // In this example, we're simply displaying the token
    successElement.querySelector(".token").textContent = result.token.id;
    successElement.classList.add("visible");

    // In a real integration, you'd submit the form with the token to your backend server
    //var form = document.querySelector('form');
    //form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
    //form.submit();
  } else if (result.error) {
    errorElement.textContent = result.error.message;
    errorElement.classList.add("visible");
  }
}

cardNumberElement.on("change", function(event) {
  setOutcome(event);
});

cardExpiryElement.on("change", function(event) {
  setOutcome(event);
});

cardCvcElement.on("change", function(event) {
  setOutcome(event);
});

// Handle credit card form submission:
var paymentForm = document.getElementById("payment-form");
$("#submit-card").on("click", function(event) {
  event.preventDefault();
  stripe.createToken(cardNumberElement).then(function(result) {
    console.log("result", result);

    if (result.error) {
      // Inform the user if there was an error
      var errorElement = document.getElementById("card-errors");
      errorElement.textContent = result.error.message;
    } else {
      // Send the token to your server
      stripeTokenHandler(result.token);
    }
  });
});

これでUser情報が書き換わる時に、Stripeカスタマートークンを作成します。

users_controller.rb
・・・
if @user.stripe_temporary_token.present?
  customer = Stripe::Customer.create(
    email: @user.email,
    source: @user.stripe_temporary_token
  )
  @user.update_attribute(:stripe_customer_id, customer.id)
  flash[:success] = "クレジットカード情報が登録されました"
end
・・・

本人確認フォームを作成する

売り手側が入金を受け取るためには本人確認書類をStripeに提出する必要があります。個人で受け取る場合と、法人で受け取る場合にて入力する内容が異なります。ドキュメントを読んで確認していきましょう。

国内で本人確認するために必要な情報は下記を参考にしていきます。
https://stripe.com/docs/connect/required-verification-information

本人確認の画像を送る際には、JSを使って直接Stripeに送信しトークンを取得する必要があります。

accounts/new.html.erb
・・・
<div class="mainItem">
  <div class="label">
    <p>本人確認書類</p>
  </div>
  <div class="mainForm">
    <div class="inputFile">
      <div
        class="preview"
        style="background-image: url('../assets/img/verification.png')"
      >
        <input accept="image/*" id="id-file" name="id-file" type="file" />
      </div>
      <p class="btn_upload">
        アップロードする
      </p>
    </div>
  </div>
</div>
・・・
verification.js
// Handle verification from submission:
var verifyForm = document.getElementById("verify-form");
$("#submit-account").on("click", function(event) {
  event.preventDefault();
  this.innerHTML =
    "<i class='fa fa-spinner fa-spin'></i> アカウント情報を登録しています...";
  this.className += " disabled";

  function() {
    // Handle a file upload
    var data = new FormData();
    data.append("file", document.querySelector("#id-file").files[0]);
    data.append("purpose", "identity_document");

    $.ajax({
      url: "https://uploads.stripe.com/v1/files",
      data: data,
      headers: {
        Authorization: `Bearer ${gon.stripe_key}`
      },
      cache: false,
      contentType: false,
      processData: false,
      type: "POST"
    }).done(function(response) {
      var fileData = response.id;
      $("input[id=stripe_file]").val(fileData);
      verifyForm.submit();
    });
  });
});

※ コントローラー部分は決済フォームで実装したものとほぼ同じですので省略させていただきます。

銀行口座フォームを作成する

続いて、売り手側が入金を受け取る銀行口座を登録していくフォームを作成していきます。
こちらは本人確認書類で作成したStripe側のアカウントを呼び起こして、そこに銀行口座の情報を追加してあげるように実装を進めていきます。

こちらも本人確認書類と同じで、下記URLを参考にして必要な情報を取得します。
https://stripe.com/docs/payouts

本人確認書類や決済フォームと同じようにJSによってStripeと交信し、取得したトークンを既存のユーザーアカウントに追加します。

user_controllers.rb
・・・
if @user.stripe_bank.present?
  stripe_account = Stripe::Account.retrieve(current_user.stripe_account_id)
  stripe_account.external_account = @user.stripe_bank
  stripe_account.save
end
・・・

定額商品を作成する

このあたりは少し我流もあったのですが、定額商品には「商品」と「プラン」の二つの概念があります。例えば、一つの会社がAとB製品を持っているのであれば、それぞれにプランを持つことになりますよね。今回に関していえば、手入力でStripe側の商品をあらかじめ作っておいて、そこに紐づくプランをユーザーがアプリケーション側でプランを作成するたびに増えていくようにしました。
(これが、ユーザーが商品に対して幾つものプランを用意することを想定する場合は商品ごとユーザーが作る必要があるかもしれませんが、今回はユーザーは一つのプランに対して一つの価格設定を前提とします。)
スクリーンショット 2019-03-21 16.11.39.png

作成した商品のIDはクレデンシャルに書き込んで保存しておきます。
あと、プラン側はアプリケーション側が作成された時に一緒に作成するようにコントローラー側で仕込むだけです。

planc_controller,rb
  def create
    @community = current_user.plans.create(create_params)
    @community.community_id = "plan_#{@plan.id}"
    if @community.save
      Stripe::Plan.create(
        product:      Rails.application.credentials[Rails.env.to_sym][:stripe][:product_id],
        id:           @plan.community_id,
        currency:     'jpy',
        interval:     'month',
        nickname:     @plan.name,
        amount:       @plan.price,
      )
      flash[:success] = "We'll let you know when your community is approved."
      redirect_to current_user
    else
      flash[:alert] = "Faild to add a community."
      redirect_to current_user
    end
  end

顧客が定額商品を契約する

クレジットカード情報を持ったユーザーが定額商品を契約します。
これによって、ユーザーとプラットフォーム側が定期支払いによって契約が交わされることになります。
顧客情報と、プラン情報だけでなく、メタ情報としてプランを作成したアカウントのIDと、プラットフォーム側の手数料比率をここでいれておくのがポイントです。

subscriptions_controller.rb
・・・
def create
  @subscription = current_user.subscriptions.create(create_params)
  if @subscription.save
    @plan_id = "plan_#{@subscription.community.id}"
    stripe_subscription = Stripe::Subscription.create(
      customer: @subscription.user.stripe_customer_id,
      plan: @community_id,
      metadata: {
        destination: @subscription.user.stripe_account_id,
        commission_fee: "20"
      }
    )
    @subscription.stripe_subscription_id = stripe_subscription.id
    @subscription.save

    redirect_to current_user
  else
    redirect_to current_user
  end
end
・・・

プラットフォームからアカウントに送金される

顧客から受け取った金額をそのまま、アカウントに送金する必要があります。
そのためには、StripeのWebhookを使って、毎月なり支払いがある度に都度、アカウント側へ送金を行なっていきます。ngrockというサービスがWebhookのローカルでのテストでは非常に便利です。
Stripeにおけるngrockの設定は下記を参照にしてください。
https://qiita.com/kakipo/items/5d7325902965e74b3091

ngrokを設定したあとは、Stripeダッシュボードのテスト画面から配信ができるようになります。
ngrok.jpg

支払いが行われる度に、プラットフォームからアカウントへ自動送金処理を実装していきます。

Stripe.rb
Rails.configuration.stripe = {
  :publishable_key          => Rails.application.credentials[Rails.env.to_sym][:stripe][:publishable_key],
  :secret_key               => Rails.application.credentials[Rails.env.to_sym][:stripe][:secret_key],
  :account_signing_secret   => Rails.application.credentials[Rails.env.to_sym][:stripe][:account_signing_secret],
  :connect_signing_secret   => Rails.application.credentials[Rails.env.to_sym][:stripe][:connect_signing_secret]
}

Stripe.api_key = Rails.configuration.stripe[:secret_key]
StripeEvent.signing_secrets = [
  Rails.configuration.stripe[:account_signing_secret],
  Rails.configuration.stripe[:connect_signing_secret],
]

StripeEvent.configure do |events|
  # 請求に成功した場合の処理
  events.subscribe(
    'invoice.payment_succeed',
    Events::InvoicePaymentSucceed.new
  )
end
services/invoice_payment_succed.rb
class Events::InvoicePaymentSucceed
  def call(event)
    source = event.data.object

    # 送金処理を行なう
    subscription = source.lines.data[0]
    metadata = subscription.metadata
    commissionPercentage = metadata.commission_fee.to_i / 100
    commissionAmount = subscription.amount * commissionPercentage
    destinationAmount = subscription.amount - commissionAmount
    destinationAccount = metadata.destination

    transfer = Stripe::Transfer.create({
      amount: destinationAmount,
      currency: 'jpy',
      destination: destinationAccount
    })
  end
end

アカウントの口座に入金される

入金はStripeダッシュボード上より、手動入金と、自動入金(月に何日、週に何曜日)など選べるみたいです。
10,000円以上残高貯まらないとできないなど、実装でカスタマイズはできるみたいです。
今回はサブスクリプションなんで、一ヶ月定期でいいんじゃないかなと思って、とりわけ実装はしませんでした。
スクリーンショット 2019-03-22 19.11.17.png

やってみると、意外にも壮大になってしまいました。。
お金を取り扱うあたり、慎重にならなきゃいけないところもありますよね。銀行口座や、本人確認書類のバリデーションもフロント側で処理できるといいですよね。なんか良いライブラリあったら、教えて欲しいです。

実際、これやり切るのに、Stripeご担当者さまに幾度となく問い合わせしました。
すぐに、優しく応答してくれて、サービスも会社も素晴らしいなと感動でした!

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

【Ruby】クラスとインスタンス

クラスとインスタンスについて

Rubyにおけるクラスとインスタンスについて理解しづらい部分も多いかと思いますので例を交えながらなるべくわかりやすく解説して行きたいと思います。

クラスとは

クラスとは共通の属性メソッドをまとめる箱のようなものです。
学校のクラスを思い出してみてください、クラスには勉強を学ぶ生徒がいます。生徒という括りでは一つとしてまとめる事ができますが、それぞれ生徒には特徴があります。男女の区別があったり、身長、体重も違います、生徒はそれぞれ個々の名前を持っていますし上げようと思えばいくらでも出てきます。これらの情報を入れておくものがクラスです。

属性とメソッドについて

それでは属性とメソッドとは何か?
上記で述べた学校のクラスを例にとると生徒には名前がありましたね、その「名前」のような個々の情報を持ったものが属性になります。また生徒たちには共通してできる事があります。食べたり、話したり、笑ったりのようにそのクラス内の全員が共通してできる事クラスメソッドです。

クラスの定義

クラスを定義する際はクラス名を大文字で定義する事がポイントです。

school.rb
class Student
end

これでStudentクラスを定義できました。

インスタンスについて

インスタンスは上記で述べた属性値とメソッドのことです。例えば「名前」という属性であれば、属性値は「ゆーいち」のような個々が持っている名前ということです。また上でも述べたようにその属性値に対してできること(処理)がインスタンスメソッドです。

インスタンスの定義

インスタンスはクラスから生成されるものなので、newメソッドを使って生成します。
newメソッドとはクラスに対して使える特別なメソッドでインスタンスを生成してくれます。

school.rb
class Student
end

student = Student.new

これでインスタンスを生成する事ができました。

最後に

今回はクラスとは何か、インスタンスとは何か。について話していきました。
詳しいメソッドなどについては長くなってしまうので、次回から何回かに分けて説明したいと思います。
最後まで読んでいただきありがとうございました。

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

CentOSにrbenvをインストールする

公式からcloneする。

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv

必要な環境変数を追加し、読み込み直す。

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

コマンドを打って確認。

$ rbenv --help
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List installed Ruby versions
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

See `rbenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/rbenv/rbenv#readme

installコマンドがない。ruby-buildがないからか。
ruby-buildをrbenvのplugins配下にインストールする。

$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

もう一回見てみる。

$ rbenv --help
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   install     Install a Ruby version using ruby-build
   uninstall   Uninstall a specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List installed Ruby versions
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

See `rbenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/rbenv/rbenv#readme

installとuninstallが追加されている。

ついでにruby(2.4.1)をインストールする。
時間はそこそこかかる。

$ rbenv install 2.4.1
Downloading ruby-2.4.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2
Installing ruby-2.4.1...

BUILD FAILED (CentOS release 6.10 (Final) using ruby-build 20190320)

Inspect or clean up the working tree at /tmp/ruby-build.20190322234150.2287
Results logged to /tmp/ruby-build.20190322234150.2287.log

Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.

Configure options used:
  --prefix=/home/xxx/.rbenv/versions/2.4.1
  LDFLAGS=-L/home/xxx/.rbenv/versions/2.4.1/lib
  CPPFLAGS=-I/home/xxx/.rbenv/versions/2.4.1/include

失敗した。
openssl, readline, zlib
ここら辺がないようなのでyumでインストールする。

$ sudo yum install -y openssl-devel readline-devel zlib-devel

再度インストールする。

$ rbenv install 2.4.1
Downloading ruby-2.4.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2
Installing ruby-2.4.1...
Installed ruby-2.4.1 to /home/xxx/.rbenv/versions/2.4.1

成功した。

$ rbenv global 2.4.1
$ ruby -v
bash: ruby: コマンドが見つかりません

ふむ…。

$ rbenv exec ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

なるほど。

$PATHに$HOME/.rbenv/shimsを追加する。

$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

無事行けたっぽい。

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