- 投稿日:2019-10-26T23:04:24+09:00
Rubyの文法 memo初心者【rails学習①】v-2
目的と内容
学習内容の整理と後日の参照用。他者へのポートフォリオ用。
今回はRuby文法のまとめ。
基本
コメント
1行の場合
#シャープ以下はコメントになる下記でも、コメントアウトにはなるが、こちらはソースコードにドキュメントを埋め込むための記述
=begin
beginとend間のドキュメントが埋め込まれる
=endメソッド
puts
画面に出力するためのメソッド、文末で改行される
画面に出力するためのメソッド、文末で改行されないRandom#rand()
引数を渡さない(もしくは引数が0)の場合、0以上1未満の浮動小数点数をランダムに生成するメソッド
rand(1..10)など、括弧内で生成する値の範囲を決められる分岐
if.rbif 条件式 処理 elsif 条件式 処理 else 処理 end繰り返し
for.rbfor カウンタ変数 in 繰り返し範囲(配列でもOK) 処理 endwhile.rbwhile 条件式 処理 カウンタ変数を更新 end型の変更
- to_i 整数へ
- to_f 浮動小数点数へ
- to_s 文字列へ
- to_a 配列へ
- to_h ハッシュへ
標準入力
gets.rbexample = gets他、chomp(末尾の改行を取り除くメソッド)と併用することが多そう。
配列
array.rbexarray = [値, 値, 値, 値] #代入 exarray.push(値) #末尾に値を追加 exarray.detete(0) #0番目を削除各要素をループで取り出したい場合
each.rbexarray.each do |変数名| 処理 end exarray.each do |変数名、変数名2| #インデックス番号も一緒に取得したい場合 処理 endメソッド
Array#map()
配列の各要素に同じ処理を加えたい場合String#split()
指定の記号で分割し、配列として戻すArray#sort
要素が<=>で比較可能であれば並び替えるArray#reverse
配列を現在と逆の順序に並び替えるハッシュ
hash.rbexhash = {値 => 値, 値 => 値, 値 => 値}キーにシンボルを使った場合、下記のようにも記述できる。
hash.rbexhash = {:値 => 値,:値 => 値,:値 => 値} #または exhash = {値:値, 値:値, 値:値}各要素をループで取り出したい場合
hash.rbexhash.each_values do |変数名| 処理 end exhash.each do |変数名, 変数名2| #キーも一緒に取り出したい場合 処理 endメソッド
method.rbdef exmethod() 処理 endメソッド内で定義された変数は独立している。
外から同じ名前の変数を使いたい場合は、\$exampleのように\$マークを先頭につけたグローバル変数をつかう必要があるが、これはあまり使われない。クラス
基本
class.rbclass Exclass @@exclass #クラス変数(よくわかっていない attr_accessor :exam def initialize(exam) #初期化メソッド(必ず実行される @exam = exam #インスタンス変数(よくわかっていない end endクラス名の最初の一文字は必ず大文字にする。
attr_accessor : ◯◯はインスタンス変数を外から変更できるようにするためのコード。(よくわかっていない)継承
親クラスのメソッド、変数を子クラスでもつかえる。
オーバーライド
親クラスが持つメソッドを、子クラスで再定義して上書きできる。
private
頭にprivateを付け加えられたメソッドはクラス内からしか呼び出せない。
superメソッド
親クラスの持つメソッドを呼び出す。
その他
ライブラリの読み込み
require 'ライブラリ名'モジュール
modu.rbmodule モジュール名 def メソッド名() end module_function :メソッド名 endモジュールはオブジェクトを作らず、メソッドをそのまま実行することができる。
その場合、『module_function :メソッド名』という記述が必要。
下記、Mix-inを使う場合、『module_function :メソッド名』の記述はつけてはいけない。(よくわかっていない部分Mix-in
mixin.rbclass クラス名 include モジュール名 end例外処理
reigai.rbbegin エラーが発生する可能性のある場所 rescue エラーが発生した場合 else エラーが発生しない場合 ensure エラーの有無に関わらず行う処理 endその他
・コマンド
ファイル名やフォルダ名にスペースが入ってる場合、コマンドでは””を含めて記述
ex)cd "new project"コマンドラインから現在いる場所をFinderで開きたい場合(Mac)
open .
- 投稿日:2019-10-26T23:04:24+09:00
Rubyの文法 memo初心者【rails学習①】
目的と内容
学習内容の整理と後日の参照用。他者へのポートフォリオ用。
今回はRuby文法のまとめ。
基本
コメント
1行の場合
#シャープ以下はコメントになる2行以上の場合
=begin
beginとend間がコメントになる
=endメソッド
puts
画面に出力するためのメソッド、文末で改行される
画面に出力するためのメソッド、文末で改行されないrand()
0〜1までの数をランダムに生成するメソッド
rand(1..10)など、括弧ないで生成する値の範囲を決められる分岐
if.rbif 条件式 処理 elsif 条件式 処理 else 処理 end繰り返し
for.rbfor カウンタ変数 in 繰り返し範囲(配列でもOK) 処理 endwhile.rbwhile 条件式 処理 カウンタ変数を更新 end型の変更
- to_i 整数へ
- to_f 浮動小数点数へ
- to_s 文字列へ
- to_h ハッシュへ
標準入力
gets.rbexample = gets他、chomp(末尾の改行を取り除くメソッド)と併用することが多そう。
配列
array.rbexarray = [値, 値, 値, 値] #代入 exarray.push() = 値 #末尾に値を追加 exarray.detete(0) #0番目を削除各要素をループで取り出したい場合
each.rbexarray.each do |変数名| 処理 end exarray.each do |変数名、変数名2| #インデックス番号も一緒に取得したい場合 処理 endメソッド
map()
配列の各要素に同じ処理を加えたい場合split()
指定の記号で分割し、配列として戻すsort
配列を文字コード順に並び替えるreverse
配列を文字コードと逆の順序に並び替えるハッシュ
hash.rbexhash = {値 => 値, 値 => 値, 値 => 値} #書き方1 exhash = {:値 => 値,:値 => 値,:値 => 値} #書き方2 exhash = {値:値, 値:値, 値:値} #書き方3各要素をループで取り出したい場合
hash.rbexhash.each_values do |変数名| 処理 end exhash.each do |変数名, 変数名2| #キーも一緒に取り出したい場合 処理 endメソッド
method.rbdef exmethod() 処理 endメソッド内で定義された変数は独立している。
外から同じ名前の変数を使いたい場合は、\$exampleのように\$マークを先頭につけたグローバル変数をつかう必要があるが、これはあまり使われない。クラス
基本
class.rbclass Exclass @@exclass #クラス変数(よくわかっていない attr_accessor :exam def initialize(exam) #初期化メソッド(必ず実行される @exam = exam #インスタンス変数(よくわかっていない end endクラス名の最初の一文字は必ず大文字にする。
attr_accessor : ◯◯はインスタンス変数を外から変更できるようにするためのコード。(よくわかっていない)継承
親クラスのメソッド、変数を子クラスでもつかえる。
オーバーライド
親クラスが持つメソッドを、子クラスで再定義して上書きできる。
private
頭にprivateを付け加えられたメソッドはクラス内からしか呼び出せない。
superメソッド
親クラスの持つメソッドを呼び出す。
その他
ライブラリの読み込み
require 'ライブラリ名'モジュール
modu.rbmodule モジュール名 def メソッド名() end module_function :メソッド名 endモジュールはオブジェクトを作らず、メソッドをそのまま実行することができる。
その場合、『module_function :メソッド名』という記述が必要。
下記、Mix-inを使う場合、『module_function :メソッド名』の記述はつけてはいけない。(よくわかっていない部分Mix-in
mixin.rbclass クラス名 include モジュール名 end例外処理
reigai.rbbegin エラーが発生する可能性のある場所 rescue エラーが発生した場合 else エラーが発生しない場合 ensure エラーの有無に関わらず行う処理 endその他
・コマンド
ファイル名やフォルダ名にスペースが入ってる場合、コマンドでは””を含めて記述
ex)cd "new project"コマンドラインから現在いる場所をFinderで開きたい場合(Mac)
open .
- 投稿日:2019-10-26T19:18:04+09:00
railsアプリに投稿されたYouTubeURLを自動的に埋め込み表示させる方法~無理やり編~
1概要
ユーザーがYouTubeにアップロードされた動画のURLを投稿し、それを自動で埋め込み動画としてそのサイトに表示させたい。これやりたい人地味に多いのでは?
実装しようとして意外と記事がなかったので僕がやったやり方を共有。
今回はrailsアプリに投稿されたYouTubeURLがたとえ埋め込みURLでなくても自動でサイトに埋め込み表示させる方法を紹介します。環境ruby 2.5.6 Rails 6.0.0こんな感じのものができる予定
1.1. YouTubeURLの種類
YouTubeURLは僕がパッと見た感じ3種類のURLが存在します
PCでのYouTube閲覧時のURL 一番スタンダード?
https://www.youtube.com/watch?v=DOEk-0MeQbI
共有用URL (スマホで視聴中の動画を友達に共有するときはこれ)
埋め込みURL (これをHTMLに貼り付ければそのページで埋め込み動画になる)
https://www.youtube.com/embed/DOEk-0MeQbI
1.2. どう実装するか
この3つのURLには共通して末尾に11桁の数字があります。これはGoogleがYouTubeに投稿された全ての動画に割り振っている通し番号でvideo_idと呼ばれます。
つまり上の2種類のURLが投稿されたら末尾の11桁を取り出し、HTMLに設置した以下の埋め込みURLの末尾にその数字を反映させれば埋め込み動画になるはずです。埋め込みURLの末尾11桁に投稿されたurlの末尾11桁を代入→ https://www.youtube.com/embed/<11桁のvideo_id>
2 実装
2.1 事前準備
それではまずここで使うYouTube動画を投稿するだけのサンプルアプリを作っていきます。
cd cd desktop rails new YouTubeApps投稿周りの機能をscaffoldを利用して一瞬で作りましょう。
cd YouTubeApps rails generate scaffold post body:text youtube_url:string rails db:migrateこれで投稿周りの機能ができたと思います。それではここからpostsテーブルのyoutube_urlカラムにどんなYouTubeURLが投稿されても埋め込みURLに変えていく記述を書いていきます。
2.2 本題
それではここからyoutubeURLから末尾のvideo_idのみを取り出し埋め込みURLにする実装をしていくのですが、Postsコントローラーのcreateアクションへrubyのコードを記述して行きます。
以下のように、scaffoldによって作成されたコントローラーのcreateアクションにコードを追記してください。posts_controller.rbdef create @post = Post.new(post_params) #追記した部分ここから url = params[:post][:youtube_url] url = url.last(11) @post.youtube_url = url #ここまで respond_to do |format| if @post.save format.html { redirect_to @post, notice: 'Post was successfully created.' } format.json { render :show, status: :created, location: @post } else format.html { render :new } format.json { render json: @post.errors, status: :unprocessable_entity } end end endここで追記した以下の部分について解説をします。
url = params[:post][:youtube_url] url = url.last(11) @post.youtube_url = urlparamsとは
まず一行目のparamsを含む一文について
url = params[:post][:youtube_url]paramsとはrailsに用意されたgetやpostで送られてきた値を格納するためのメソッドです。
paramsのわかりやすい解説記事
ここでは投稿する際にformによってcreateアクションにpostの内容が[:body][:youtube_url]として送られています。
posts_controllerurl = params[:post][:youtube_url]よって、上記のコードにより変数urlに対してparamsに格納している中身であるformによって送られてきた[:youtube_url]の値を格納します。
現在の変数urlの中身は送られてきたurl全文が格納されている状態です。現在の変数urlの中身
https://www.youtube.com/watch?v=DOEk-0MeQbIlastメソッドについて
ここから二文目のコードで語尾の11桁のvideo_idを取り出します。
url = url.last(11)rubyの配列にはlastというメソッドがあります。これを呼ぶことで配列に対してその最後の要素を取得することができます。また、(n)の中に引数として0以上の値を渡すことで、最後のn個の要素を取得することができます。
a=[0,1,2,3] a.last(2) #=>[2,3]つまりこの
url = url.last(11)で変数urlに格納されていたyoutube_urlの値のなかで最後の11桁の値のみを取り出し、改めて変数urlに格納するという処理をしています。
最後の三文目
@post.youtube_url = urlここではviewで使用するインスタンス変数@postへ↑の変数urlの値を格納することでviewで@post.youtube_urlの値を呼び出すとvideo_idの値を返すようにします。
viewの処理
viewではposts/showおよびposts/indexページに埋め込みurlを用意しておきます。
posts/show.html.erb<p id="notice"><%= notice %></p> <p> <strong>Body:</strong> <%= @post.body %> </p> <p> <strong>Youtube url:</strong> <%= @post.youtube_url %> </p> <%= link_to 'Edit', edit_post_path(@post) %> | <%= link_to 'Back', posts_path %>上記の<%= @post.youtube_url %>の部分を以下のように書き換えます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/<%= @post.youtube_url%>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>YouTubeの埋め込みurlを用意し末尾のvideo_idが入る部分に@post.youtube_urlの値が入るようにすることで、viewの中でどんなYouTubeURLが来ても埋め込み動画にするようにしています。
posts/index.html.erbも同様に
posts/index.html.erb<% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.youtube_url %></td> <td><%= link_to 'Show', post %></td> <td><%= link_to 'Edit', edit_post_path(post) %></td> <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %>の<%= post.youtube_url %>部分に以下のコードを代入します
<iframe width="560" height="315" src="https://www.youtube.com/embed/<%=post.youtube_url%>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>これでこのように表示されていれば完璧です。
終わり
以上です。少し無理やりですが、YouTubeURLを投稿されたら埋め込み動画にするrailsアプリを作ってみました。
謝辞
ありがとうまこっちゃん
- 投稿日:2019-10-26T16:27:35+09:00
【Ruby on Rails】rails generate devise:install で terminal が止まる
現象
https://qiita.com/Hal_mai/items/350c400e8763ce0487a3
上記の記事を参考にdeviseを導入した際に、以下のコマンドを叩いた時に、 Railsコマンドが動かなくなった。
rails generate devise:install解決策
Rails application preloader の
springを一旦停止させる。bundle exec spring stop参考
https://qiita.com/Hal_mai/items/350c400e8763ce0487a3
https://github.com/rails/spring
- 投稿日:2019-10-26T16:22:27+09:00
Uncaught TypeError: Cannot read property 'observe' of undefined
Uncaught TypeError: Cannot read property 'observe' of undefined
mutation observerを使用するところでエラーが発生。
解決策:
$(document).ready(function () {~~~~の記述を追加する。
readyがないと動きませんでした。
- 投稿日:2019-10-26T15:27:42+09:00
初心者用競技プログラミングの入力方法まとめ(ruby)
はじめに
この記事は以下のruby初学者を想定しております
・rubyを使い始めて配列や繰り返し処理、ハッシュなどの概念を理解しているかた。
・paizaやAtcoderなどの競技プログラミングに興味があるけど問題で与えられた数値の適切な取り込み方がわからないかた。私もはじめ与えられた数値が適切に取得できずに苦労したのでまとめを残しておきます。
1次元の数値の取り込み
整数一つの場合
10
という数値が与えられてそれを取得する場合は
N = gets.to_i puts Nコンソール10 :入力値 10 :出力値上記のコンソール画面のように10を入力して10が出力されるはずです。
一列で複数の整数が与えられる場合
1 2 3 … s
上記のような数値間に半角スペースが数列を入力する場合は数列で取り込むのが簡単なやり方です。
N = gets.chomp.split.map(&:to_i) puts Nコンソール1 2 3 4 5 :入力値 1 :出力値 2 3 4 5コードの説明の説明をすると
chompは文字列の末尾の改行文字を取り除いた新しい文字列を返します。(これがないと半角スペースによる改行判定で先頭1文字しか入力できなくなってしまいます。)
splitは文字列を分割し、配列を返すメソッドです。
map(&:to_i)はおなじみの繰り返しメソッドですが末尾に(&:to_i)を宣言することでinteger 型で入力値を読み込めます。配列を出力する場合、putsを用いると1文字ごとに改行して出力することに注意してください。
2次元の数値の取り込み
N K Q :N K Qは全て整数
A1
A2
.
.
.
AQ :Aの横の数字はQ番目の数値という意味上記のように一列目を取り込んだ後に、
1行ごとにQ個の数を入力する場合はやり方としてはN, K, Q = gets.chomp.split.map(&:to_i) A = Q.times.map { gets.to_i } puts Aコンソール6 3 4 :入力値 3 1 3 2 3 :出力値 1 3 2これらの組み合わせができればある程度の問題までは対応できました。
文字列に関しても to_i を to_s に変えれば大丈夫です。
その他のテクニック(sortを使った並べ替え)
最後に使えると便利な小技として並べ替え(sort)の紹介をしたいと思います。
5 4 7 11 9 2 42 1
入力値として上記の数字の列を与えられて小さい順や大きい順に並べ替えたい時sortのメソッドを使うと便利です。(知らずに苦労してた時期も私にはありました。笑)
N = gets.chomp.split.map(&:to_i) N.sort! p N N..sort! {|a, b| b <=> a } p Nコンソール5 4 7 11 9 2 42 1 :入力値 [1, 2, 4, 5, 7, 9, 11, 42] :出力値 [42, 11, 9, 7, 5, 4, 2, 1]コンソールを見てみると
1回目の出力で小さい順に並んでいて
2回目の出力で大きい順に並んでいます。これらのテクを使えば競プロの簡単な問題は解けるようになるはずです。
私も競技プログラミング初心者ですが、一緒に頑張っていきましょう。
- 投稿日:2019-10-26T15:21:54+09:00
AWS Cloud9 に Ruby 2.5.0 と thinreports gem を インストールして Lambda で PDFを生成する方法
はじめに
AWS Cloud9 環境にて Rubyで作成した Lambda関数を Cloud9でzip圧縮→Lambdaにアップロードして動かすまでやってみました。
ポイントは下記の通り
- LambdaのRubyランタイムと合わせる為に、Cloud9 に rvm で Ruby 2.5.0 をインストール
- S3バケットにLambda関数からPDFファイルを書き込む為の権限設定
最終的に、[kintone] → [API Gateway] → [Lambda] → [PDF生成] → [/tmp保存] → [kintone添付ファイルに保存] までの予定ですが、まず [/tmp保存] まで実装します。
実装イメージ
今回はオレンジ色の範囲を実装します。
実行環境
- AWS Cloud9
- macOS 10.13.6
- Ruby 2.5.0
処理の流れ
- Cloud9 に Ruby 2.5.0 をインストール
- kintoneアプリ作成→PDF生成処理の[Lambda]関数を実行する[API Gateway]を叩くJSを仕込みます
- PDF生成用のPDFレイアウトファイルの作成
- PDF生成用のLambda関数の作成
- S3バケットの権限設定
- S3バケットにPDFファイルを生成できることを確認
- /tmp にPDFファイルを保存
一旦前回の処理と同様にS3にPDFファイルを生成することが出来ることを確認してから、/tmpに保存してみたいと思います。
0.(事前準備)Cloud9 に Ruby 2.5.0 をインストール
(2019-10-25現在)Lambdaで実行される Rubyランタイム のバージョンは 2.5.0 です。
作成するライブラリやディレクトリ構成も合わせる必要があるので、Cloud9 に rvm を利用して Ruby 2.5.0 をインストールします。
また、今回必要なライブラリも bundler で プロジェクトディレクトリの下の vendoer/bundle にインストールします。(最終的にZipでまとめて Lambda にアップロードする為です)rvm で Ruby 2.5.0 をインストール
ターミナルから rvm で Rubyをインストールしていきます。
rvm listで確認すると、現在は Ruby 2.6.0 がデフォルトでインストールされています。
rvm install ruby 2.5.0で Ruby 2.5.0 をインストールします。$ rvm list =* ruby-2.6.3 [ x86_64 ] # => - current # =* - current && default # * - default $ rvm install 2.5.0 $ rvm install 2.5.0 Warning, new version of rvm available '1.29.9', you are using older version '1.29.8'. You can disable this warning with: echo rvm_autoupdate_flag=0 >> ~/.rvmrc You can enable auto-update with: echo rvm_autoupdate_flag=2 >> ~/.rvmrc Searching for binary rubies, this might take some time. No binary rubies available for: amazon/2018.03/x86_64/ruby-2.5.0. Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies. Checking requirements for amazon. Requirements installation successful. Installing Ruby from source to: /home/ec2-user/.rvm/rubies/ruby-2.5.0, this may take a while depending on your cpu(s)... ruby-2.5.0 - #downloading ruby-2.5.0, this may take a while depending on your connection... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 13.3M 100 13.3M 0 0 28.0M 0 --:--:-- --:--:-- --:--:-- 28.0M ruby-2.5.0 - #extracting ruby-2.5.0 to /home/ec2-user/.rvm/src/ruby-2.5.0..... ruby-2.5.0 - #applying patch /home/ec2-user/.rvm/patches/ruby/2.5.0/prelude_gcc_diagnostic.patch. ruby-2.5.0 - #applying patch /home/ec2-user/.rvm/patches/ruby/2.5.0/libressl_2_7.patch. ruby-2.5.0 - #configuring................................................................... ruby-2.5.0 - #post-configuration.. ruby-2.5.0 - #compiling................................................................................... ruby-2.5.0 - #installing............................. ruby-2.5.0 - #making binaries executable.. ruby-2.5.0 - #downloading rubygems-3.0.6 ruby-2.5.0 - #extracting rubygems-3.0.6...... ruby-2.5.0 - #removing old rubygems........ ruby-2.5.0 - #installing rubygems-3.0.6............................................... ruby-2.5.0 - #gemset created /home/ec2-user/.rvm/gems/ruby-2.5.0@global ruby-2.5.0 - #importing gemset /home/ec2-user/.rvm/gemsets/global.gems................................................................ ruby-2.5.0 - #generating global wrappers....... ruby-2.5.0 - #gemset created /home/ec2-user/.rvm/gems/ruby-2.5.0 ruby-2.5.0 - #importing gemsetfile /home/ec2-user/.rvm/gemsets/default.gems evaluated to empty gem list ruby-2.5.0 - #generating default wrappers....... ruby-2.5.0 - #adjusting #shebangs for (gem irb erb ri rdoc testrb rake). Install of ruby-2.5.0 - #complete Please be aware that you just installed a ruby that requires 2 patches just to be compiled on an up to date linux system. This may have known and unaccounted for security vulnerabilities. Please consider upgrading to ruby-2.6.3 which will have all of the latest security patches. Ruby was built without documentation, to build it run: rvm docs generate-ri admin-user:~/environment $ rvm list => ruby-2.5.0 [ x86_64 ] * ruby-2.6.3 [ x86_64 ] # => - current # =* - current && default # * - default $ ruby -v ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]bundle install で aws-sdk-s3, thinreports をインストール
Ruby 2.5.0 がインストールされ利用できる様になりました。
次は以下の2つのRubyライブラリをインストールします。プロジェクトのディレクトリに移動して、
bundle init
出来たGemfileに追記gem 'thinreports' gem 'aws-sdk-s3', '~> 1'
bundle installを実行します$ bundle install Fetching gem metadata from https://rubygems.org/............... Resolving dependencies... Fetching aws-eventstream 1.0.3 Installing aws-eventstream 1.0.3 Fetching aws-partitions 1.228.0 Installing aws-partitions 1.228.0 Fetching aws-sigv4 1.1.0 Installing aws-sigv4 1.1.0 Fetching jmespath 1.4.0 Installing jmespath 1.4.0 Fetching aws-sdk-core 3.72.0 Installing aws-sdk-core 3.72.0 Fetching aws-sdk-kms 1.25.0 Installing aws-sdk-kms 1.25.0 Fetching aws-sdk-s3 1.51.0 Installing aws-sdk-s3 1.51.0 Using bundler 1.17.3 Fetching pdf-core 0.7.0 Installing pdf-core 0.7.0 Fetching ttfunk 1.5.1 Installing ttfunk 1.5.1 Fetching prawn 2.2.2 Installing prawn 2.2.2 Fetching thinreports 0.10.3 Installing thinreports 0.10.3 Bundle complete! 2 Gemfile dependencies, 12 gems now installed. Bundled gems are installed into `./vendor/bundle`ディレクトリ構成確認
プロジェクトディレクトリは下記の構成になっています。
|--hello-world.rb |--hello_world.tlf |--kintoneToPdf | |--index.js |--template.yaml |--vendor | |--bundle | | |--ruby | | | |--2.5.0 | | | | |--bin | | | | |--build_info | | | | |--cache | | | | |--doc | | | | |--extensions | | | | |--gems | | | | | |--aws-sdk-s3-1.51.0 | | | | | | |--lib | | | | | | | |--aws-sdk-s3 | | | | | | | | |--bucket_acl.rb | | | | | | | | |--bucket_cors.rb | | | | | | | | |--bucket_lifecycle_configuration.rb | | | | | | | | |--bucket_lifecycle.rb | | | | | | | | |--bucket_logging.rb | | | | | | | | |--bucket_notification.rb | | | | | | | | |--bucket_policy.rb | | | | | | | | |--bucket.rb | | | | | | | | |--bucket_region_cache.rb | | | | | |--thinreports-0.10.3 | | | | | | |--CHANGELOG.md | | | | | | |--fonts | | | | | | |--Gemfile | | | | | | |--lib | | | | | | | |--thinreports | | | | | | | | |--config.rb | | | | | | | | |--corevendor/bundle/ruby/2.5.0/gems 以下に aws-sdk-s3, thinreports の Ruby gems(ライブラリ) がインストールされました。
1. kintoneアプリ作成
次の拙稿の記事を参考にして下さい。
https://qiita.com/sy250f/items/0f2aaf17fd670bf82c84#kintone%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%9C%E6%88%902. Thinreportsレイアウトファイルの作成
Thinreports は Thinreports Editorを使って作成したレイアウトファイルをテンプレートとして、PDFを生成します。
作成したレイアウトファイルは、後ほど Zip圧縮するためにCloud9のプロジェクトディレクトリにアップロードしておきます。
3. AWS Lambad for Ruby と Thinreports によるPDF出力
前段の記事では、ローカルの mac環境で作成したプログラムをZipにしてLambdaにアップロードしていました。
今回は Cloud9環境 で Lambda を作成してデプロイしてみます。Cloud9 から Lambdaアプリの作成
新しく Lambdaアプリを作成していきます。
λ+(create new lambda function)ボタンから作成していきます。下記スクリーンショットを参考にしてください。2.ファイル名、アプリ名入力(ディレクトリは アプリ名/ファイル名/ になります)
3.blueprintの選択に Ruby が無いのでとりあえず Node.js を選びます。
5.ロールは自動作成にします。
後ほどS3の権限も合わせて調整します。
Ruby にて Lambda関数 の作成
Ruby にて Lambda関数を作成します。
Lambdaアプリの直下のディレクトリに右クリックして [hello_world.rb] を作成します。
コードは上記をそのままコピーします。
zipファイル作成
Lambdaの実行に必要なファイルをzip圧縮します。
必要なファイルとフォルダは下記の通り。
- hello-world.rb(プログラム本体)
- hello_world.tlf(Thinreports Editor で作成したレイアウトファイル)
- vendor(gemファイルのディレクトリ)
zip -r アーカイブファイル名 圧縮するファイルやディレクトリをスペース区切りで指定。
詳しくは
man zipにて確認してください。$ ls -la total 42076 drwxr-xr-x 6 ec2-user ec2-user 4096 Oct 26 01:21 . drwxr-xr-x 8 ec2-user ec2-user 4096 Oct 24 00:35 .. -rw-r--r-- 1 ec2-user ec2-user 349 Oct 24 02:26 .application.json drwxrwxr-x 2 ec2-user ec2-user 4096 Oct 24 02:55 .bundle -rw-r--r-- 1 ec2-user ec2-user 189 Oct 25 15:57 Gemfile -rw-rw-r-- 1 ec2-user ec2-user 784 Oct 26 00:19 Gemfile.lock drwxrwxr-x 8 ec2-user ec2-user 4096 Oct 24 01:15 .git -rw-r--r-- 1 ec2-user ec2-user 34 Oct 24 02:53 .gitignore -rw-r--r-- 1 ec2-user ec2-user 1498 Oct 25 09:23 hello-world.rb -rw-r--r-- 1 ec2-user ec2-user 56945 Oct 24 13:07 hello_world.tlf drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 24 22:24 kintoneToPdf -rw-r--r-- 1 ec2-user ec2-user 841 Oct 24 06:15 template.yaml drwxrwxr-x 3 ec2-user ec2-user 4096 Oct 26 00:19 vendor $ zip -r hello-world.zip hello-world.rb hello_world.tlf vendor $ ls -la total 42076 drwxr-xr-x 6 ec2-user ec2-user 4096 Oct 26 01:21 . drwxr-xr-x 8 ec2-user ec2-user 4096 Oct 24 00:35 .. -rw-r--r-- 1 ec2-user ec2-user 349 Oct 24 02:26 .application.json drwxrwxr-x 2 ec2-user ec2-user 4096 Oct 24 02:55 .bundle -rw-r--r-- 1 ec2-user ec2-user 189 Oct 25 15:57 Gemfile -rw-rw-r-- 1 ec2-user ec2-user 784 Oct 26 00:19 Gemfile.lock drwxrwxr-x 8 ec2-user ec2-user 4096 Oct 24 01:15 .git -rw-r--r-- 1 ec2-user ec2-user 34 Oct 24 02:53 .gitignore -rw-r--r-- 1 ec2-user ec2-user 1498 Oct 25 09:23 hello-world.rb -rw-r--r-- 1 ec2-user ec2-user 56945 Oct 24 13:07 hello_world.tlf -rw-rw-r-- 1 ec2-user ec2-user 42976393 Oct 26 01:21 hello-world.zip drwxr-xr-x 2 ec2-user ec2-user 4096 Oct 24 22:24 kintoneToPdf -rw-r--r-- 1 ec2-user ec2-user 841 Oct 24 06:15 template.yaml drwxrwxr-x 3 ec2-user ec2-user 4096 Oct 26 00:19 vendor出来たzipファイルはzipファイル上で右クリック→ダウンロードを選択して、ローカルへダウンロードします。
4. Lambda 及び S3 バケットへの権限設定
S3に書き込み権限を付与した[IAM]を作成して、LambdaにIAMを設定します。
また、S3バケットに作成した[IAM]にてオブジェクト(今回はPDF)を書き込める様に設定します。下記の図の様に権限設定を行います。
IAM ポリシー
Lambdaの実行ポリシーとS3バケットの書き込み権限を付けます。
Lambdaの実行権限を付与
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" } ] }S3への書き込み権限を付与
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::S3バケット名/*" } ] }S3バケットの権限設定
{ "Id": "Policy9999999999", "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt9999999999", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::バケット名", "arn:aws:s3:::バケット名/*" ], "Principal": { "AWS": [ "arn:aws:iam::Lambdaに設定したIAMロール" ] } } ] }5. S3バケットに生成したPDFの出力を確認する
kintoneアプリに設置したボタンをクリックしてLabmdaを実行し、S3にPDFが生成されていることを確認します。
S3バケットにzipファイルをアップロード
LambdaにS3のzipファイルをアップロード
関数コードをS3からアップロードします。先ほどコピーしたURLを貼り付けます。
kintoneアプリからLambdaを実行
PDFファイルの生成を確認
6. /tmp ディレクトリにPDF出力
コードを編集して、Lambda の /tmp ディレクトリにPDFを出力してみます。
hello_world.rb# coding: utf-8 require 'thinreports' require 'json' require 'aws-sdk-s3' def lambda_handler(event:, context:) begin print 'JSON.parse event.body => ' pp JSON.parse(event["body"]) event_body = JSON.parse(event["body"]) record = event_body["record"] print 'record => ' pp record puts '$id => ', record["$id"]["value"] puts 'text => ', record["text"]["value"] rescue => e puts "#{e.class}: #{e.message}" puts e.backtrace end begin region = 'S3バケットのリージョン' bucket_name = 'バケット名' key = 'put-hello-ruby.pdf' # S3 Backet Object init s3 = Aws::S3::Resource.new(region: region) obj = s3.bucket(bucket_name).object(key) report = Thinreports::Report.new layout: 'hello_world' # 1st page report.start_new_page report.page.item(:world).value(record["$id"]["value"]) report.page.item(:thinreports).value(record["text"]["value"]) obj.put(body: report.generate) # /tmpファイルに書き込み filename = '/tmp/put-hello-ruby-' + Time.new.localtime("+09:00").strftime("%Y%m%d%H%M%S") + '.pdf' puts filename File.open(filename, 'w+') { |f| f<< report.generate } puts `ls -la /tmp` rescue => e puts "#{e.class}: #{e.message}" puts e.backtrace end { statusCode: 200, body: JSON.generate('Hello Lambda! Thinreports for Ruby') } endログの表示
JSON.parse event.body => {"type"=>"app.record.detail.show", "appId"=>219, "recordId"=>3, "record"=> {"レコード番号"=>{"type"=>"RECORD_NUMBER", "value"=>"3"}, "更新者"=> {"type"=>"MODIFIER", "value"=>{"code"=>"aaaaa", "name"=>"アプリ管理者"}}, "作成者"=>{"type"=>"CREATOR", "value"=>{"code"=>"aaaaa", "name"=>"アプリ管理者"}}, "更新日時"=>{"type"=>"UPDATED_TIME", "value"=>"2019-10-26T05:01:00Z"}, "作成日時"=>{"type"=>"CREATED_TIME", "value"=>"2019-10-26T05:01:00Z"}, "text"=>{"type"=>"SINGLE_LINE_TEXT", "value"=>"/tmp に保存"}, "$revision"=>{"type"=>"__REVISION__", "value"=>"1"}, "$id"=>{"type"=>"__ID__", "value"=>"3"}}} record => {"レコード番号"=>{"type"=>"RECORD_NUMBER", "value"=>"3"}, "更新者"=>{"type"=>"MODIFIER", "value"=>{"code"=>"aaaaa", "name"=>"アプリ管理者"}}, "作成者"=>{"type"=>"CREATOR", "value"=>{"code"=>"aaaaa", "name"=>"アプリ管理者"}}, "更新日時"=>{"type"=>"UPDATED_TIME", "value"=>"2019-10-26T05:01:00Z"}, "作成日時"=>{"type"=>"CREATED_TIME", "value"=>"2019-10-26T05:01:00Z"}, "text"=>{"type"=>"SINGLE_LINE_TEXT", "value"=>"/tmp に保存"}, "$revision"=>{"type"=>"__REVISION__", "value"=>"1"}, "$id"=>{"type"=>"__ID__", "value"=>"3"}} $id => 3 text => /tmp に保存 /tmp/put-hello-ruby-20191026143607.pdf total 56 drwx------ 2 sbx_user1051 495 4096 Oct 26 05:36 . dr-xr-xr-x 21 root root 4096 Sep 24 18:18 .. -rw-rw-r-- 1 sbx_user1051 495 49084 Oct 26 05:36 put-hello-ruby-20191026143607.pdf/tmp フォルダにPDFが出力されました。
あとがき
昨日(2019-10-25 Fri)、JAWS-UG浜松 というAWSのユーザー会に参加しました。
今回は参加された方がそれぞれ発表する会の様で、サーバーレスで顔認識するWebアプリの話(Vue,Lambda,Python,DynamoDB,Amplify,AppSync,KMS,OpenCVなど利用)。サーバーレスでブログを作った話(Vue,Python,Lambda,Cognitoなど)。AWSとラズパイで工場にMESを導入した話。などなどとても刺激になる話が聞けてモチベーションだけは高まりました。特にAWSとラズパイの話は興味深かったです。ラズパイを工場のラインに設置して工作機械からの信号をラズパイで受けて3G回線で[AWS IoT]へ送り、CloudWatch,Athena,Kinesis,QuickSightなどで分析してリアルタイムで工場のラインの出来高や稼働率をダッシュボードで表示。工場の異常はビデオで撮影。またデータはDynamoDBに保存。ラズパイを使ったハード回りやプログラミングも全て一人で行ったというのがすごかった。
CloudWathもBIとして使えるなど、AWSのサービスは知らないことが多いなと思いました。
今後も定期的にJAWS-UGに参加したいです。懇親会も楽しかった。今後やりたいこと
下記のサービスを触ってみたいと思います。
参考リンク
AWS関連
- AWS S3 ポリシーでのアクセス許可の指定
- S3 バケットポリシーを追加する方法
- AWS Lambda 関数を使用する際のベストプラクティス
- Amazon S3: S3 バケットのオブジェクトへの読み取りおよび書き込みアクセスを許可する
- AWS Cloud9 の高度な AWS Lambda チュートリアル
- AWS Lambda ランタイム
- AWS SDK for Ruby - Version 3
Ruby関連
- 投稿日:2019-10-26T12:50:29+09:00
CatalinaでSassがインストールできないとき試したこと。
最初に
先日初めてMacbookを購入しSassを導入しようとしたときに
かなり手こずってしまったので備忘録としてここに残します。よく見かける方法
MacにははじめからRubyがインストールされているため、
特別な準備などはいらず、ターミナルに以下のコードを入力するだけ
$ gem install sassなどとよく書かれているのを目にするのですが
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory書き込み権限がないため当然このようなテキストが返されます。
どうもこれ、OS X 10.11 El Capitanからのようで/usrや/binなどの
ディレクトリにアクセスできないようになっているとかで。ディレクトリを変えてみる
どうにもできないと思って
検索をかけてみたところアクセスができないなら別のディレクトリに
入れれば大丈夫!との記事を見つけたため実践。
$ sudo gem install sass -n /usr/local/bin/さあこれで…と思いきやまたエラー。
rubyは間違いなく入ってるので正直エラーの原因がわからない…首をかしげながらいろんな記事を読んでは施行するも
結局は同じような内容なのでかわらず。突然の解決
きっとこれも違うだろうなと思いながら検索して出てきた文字を入力。
そしていつものようにパスワードをっと…
$ sudo gem install -n /usr/local/bin sassあれ、なんか反応が違う…
エラーが返ってこない!
これはもしやインストールできたのでは…!!と試しにバージョンを確認。
$ sass -v
Ruby Sass 3.7.4終わった…
Rubyをアップデートするために四苦八苦してみたことが
役に立ったのかそれとも上記のコードを
試した結果なのかは定かではありませんがなんとかなりました。最後に
一応下記に自分が試したものを掲載して終わりにしようと思います。
https://github.com/ffi/ffi/issues/651#issuecomment-538723566
(4のRVM導入で躓いたので途中までですが)検証もままならないような覚書で申し訳ありませんが、
お役に立てれば幸いです。また、実際に試してみた方や間違いがあれば
コメントいただければありがたいです。
- 投稿日:2019-10-26T11:48:24+09:00
docker-composeでBundler::GemNotFoundになる
- 投稿日:2019-10-26T04:37:38+09:00
【Ruby on Rails】Google Map APIの導入
はじめに
つくるもの
Google Map APIを導入しページに地図を表示させます。
今回は検索した住所にピンを立て、そこの緯度経度を表示させるまでを実装します。コードを書く前に
Google Maps API を利用するには、API キーという許可証のようなものを取得する必要があります。
API キーを取得する為にGoogle アカウントが必要になるので、事前に準備しておきましょう。そしてGoogle Cloud Platformへアクセスして、APIキーを取得しましょう。
プロジェクトの作成
APIの有効化
APIキーの作成
移行ツール
課金設定をしていないと、いざ地図を表示しようとしてもエラーが出てしまいます。
エラー文は以下の通りです。
You have exceeded your request quota for this API.
See https://developers.google.com/maps/documentation/javascript/error-messages?utm_source=maps_js&utm_medium=degraded&utm_campaign=billing#api-key-and-billing-errors移行ツール にアクセスし、手順にしたがって登録します。
アプリケーション作成
長きにわたる諸々の設定おつかれさまでした。
ここから早速アプリケーションを作っていきましょう。ファイルを作成する前に先ほど作成したAPIキーを用意しておいてください。
登場人物
今回作成・編集するページは
- routes.rb
- maps_controller.rb
- index.html.erb
この3つです。それぞれのファイルに書き込んでください。
ルーティング
routes.rbRails.application.routes.draw do get 'maps/index' root to: 'maps#index' resources :maps, only: [:index] endコントローラー
maps_controller.rbclass MapsController < ApplicationController def index end endビューページ
ビュー作成
地図を表示させる
では以下のコードをファイルにコピーしてみましょう。
index.html.erb<h2>gmap</h2> <div id='map'></div> <style> #map { height: 600px; width: 600px; } </style> <script> let map function initMap(){ geocoder = new google.maps.Geocoder() map = new google.maps.Map(document.getElementById('map'), { center: {lat: 40.7828, lng:-73.9653}, zoom: 12, }); marker = new google.maps.Marker({ position: {lat: 40.7828, lng:-73.9653}, map: map }); } </script> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>
<style>タグでマップの大きさを指定していますが、ここを省いてしまうと地図が表示されないので必ず書きましょう。<style>#map {height: 600px;width: 600px;}</style>次に地図の初期設定についてですが、
centerで初期位置の緯度経度を指定し、zoomで表示領域の大きさを決めます。function initMap(){ geocoder = new google.maps.Geocoder() map = new google.maps.Map(document.getElementById('map'), { //latが緯度、lngが経度を示します center: {lat: 40.7828, lng:-73.9653}, //数値は0〜21まで指定できます。数値が大きいほど拡大されます zoom: 12, }); //positionに指定した座標にピンを表示させます marker = new google.maps.Marker({ position: {lat: 40.7828, lng:-73.9653}, map: map }); }そして最後の行の
YOUR_API_KEYの部分に自分で作成したキーを入れてください。<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>ではここで実際にブラウザで地図が表示されるか確認してみましょう。
以下のように表示されたでしょうか?検索フォームから住所を特定しピンを刺す
次に検索フォームを作成します。
index.html.erb<h2>gmap</h2> <!-- ここから追加 --> <input id="address" type="textbox" value="GeekSalon"> <input type="button" value="Encode" onclick="codeAddress()"> <!-- ここまで追加--> <div id='map'></div> <style> #map { height: 600px; width: 600px; } </style> <script> let map function initMap(){ geocoder = new google.maps.Geocoder() map = new google.maps.Map(document.getElementById('map'), { center: {lat: 40.7828, lng:-73.9653}, zoom: 12, }); marker = new google.maps.Marker({ position: {lat: 40.7828, lng:-73.9653}, map: map }); } // ここから追加 let geocoder function codeAddress(){ let inputAddress = document.getElementById('address').value; geocoder.geocode( { 'address': inputAddress}, function(results, status) { if (status == 'OK') { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert('該当する結果がありませんでした:' + status); } }); } // ここまで追加 </script> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>2箇所追加しました。
ビューに関する部分では検索フォームとボタンを作成しました。<input id="address" type="textbox" value="GeekSalon"> <input type="button" value="Encode" onclick="codeAddress()">次に
<script>タグ内に検索機能の処理を追加しました。let geocoder //検索フォームのボタンが押された時に実行される function codeAddress(){ //検索フォームの入力内容を取得 let inputAddress = document.getElementById('address').value; geocoder.geocode( { 'address': inputAddress}, function(results, status) { //該当する検索結果がヒットした時に、地図の中心を検索結果の緯度経度に更新する if (status == 'OK') { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { //検索結果が何もなかった場合に表示 alert('該当する結果がありませんでした:' + status); } }); }では早速ブラウザを開いて見てみましょう。
以下のように検索結果に応じて結果が処理される機能をつけました。検索結果から緯度経度を取得し、表示させる
さて初めてのGoogleマップ講座もいよいよ大詰めです。
最後に検索結果の緯度経度をページに表示させましょう。コードは以下の通りです。
index.html.erb<h2>gmap</h2> <input id="address" type="textbox" value="GeekSalon"> <input type="button" value="Encode" onclick="codeAddress()"> <!-- 下の1行を追加 --> <div id="display">何かが表示される、、、、!</div> <div id='map'></div> <style> #map { height: 600px; width: 600px; } </style> <script> let map let geocoder // 下の1行を追加 const display = document.getElementById('display') function initMap(){ geocoder = new google.maps.Geocoder() map = new google.maps.Map(document.getElementById('map'), { center: {lat: 40.7828, lng:-73.9653}, zoom: 12, }); marker = new google.maps.Marker({ position: {lat: 40.7828, lng:-73.9653}, map: map }); } function codeAddress(){ let inputAddress = document.getElementById('address').value; geocoder.geocode( { 'address': inputAddress}, function(results, status) { if (status == 'OK') { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); // 下の1行を追加 display.textContent = "検索結果:" + results[ 0 ].geometry.location } else { alert('該当する結果がありませんでした:' + status); } }); } </script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB9Uo-0D2PoQaAECrt9UXceHO7S1gveNd0&callback=initMap" async defer></script>ビューに関して1箇所、
<script>タグ内に2箇所追加しました。
それぞれ追加する場所を確認し、追加して見てください。
追加した要素・処理は
- 検索結果を表示させるためのディスプレイ
- ディスプレイの情報を取得
- 検索結果をディスプレイに表示
の3つです。なので追加箇所も3箇所です。
これでコードの書き込みは完了です。ではでは最後にブラウザを開いて確認してみましょう。
検索結果がディスプレイに表示されれば完成です。次回に続く!
- 投稿日:2019-10-26T00:27:28+09:00
自分用メモ:rbenvとruby_buildをインストールしてrubyをインストールする手順でハマった話
ハマった話シリーズ。
やりたいこと
・特定のユーザにのみrubyをインストールさせたい
・rubyのインストールにはrbenvとruby_buildを用いたい
・インターネットアクセスせず完全ローカル上で完結させたい
・すべてansible playbookで自動化することディレクトリ構成
├── roles │ └──middle │ └── ruby │ └── files │ │ └── opt │ │ └── node1 │ │ │ └── .bash_profile │ │ │ └── .rbenv # rbenvとruby_buildのzipパッケージはここに配置する │ │ │ └── plugins # 必要なrpmはすべてここに格納 │ │ └── node2 │ │ └──以下node1と同一構成 │ └── tasks │ └── main.yml └── vars └── middle_var.yml └── usr_var.yml※rubyに関係する箇所以外のnode情報は他で記述しているためここでは割愛
参考
https://qiita.com/inouet/items/478f4228dbbcd442bfe8
その他情報
・OSはCentOS7.4
・rubyはデフォルトでは2.0.0がインストールされている手順概要
1.グループ作成
2.ユーザーアカウント作成
3.ソースディレクトリ作成
4.ruby依存パッケージを事前にインストール
5.rbenvインストール
6.ruby_buildインストール
7..bash_profile配布と編集
8.シェルとソースのリフレッシュ
9.rubyインストール
10.rubyバージョン切り替え手順詳細
※ここではnode1とnode1_usrのみ記述するが、node2_usrも同様にymlに記述すること
1.グループ作成
usr_var.ymlでよしなに記述してある前提で書くので変数の個所は割愛- name: ■ アカウント一覧 - Group group: name: "{{ item.group }}" gid: "{{ item.gid }}" with_items: - "{{ node1_usr }}"node2_usrも同様に記述する。
2.ユーザーアカウント作成
- name: ■ アカウント一覧 - ユーザ user: #state: absent #ユーザを削除するときはコメントを外す name: "{{ item.name }}" uid : "{{ item.uid }}" password: "{{ item.password | password_hash('sha512') }}" #変数からパスワード情報を取得し、ハッシュ化してパスワードを設定 group: "{{ item.group }}" home : "{{ item.home }}" shell: /bin/bash update_password: on_create #ユーザ作成時パスワード設定 with_items: - "{{ node1_usr }}" no_log: True #パスワード、マスク when: node1_usr #postgres_user3.ソースディレクトリ作成
- name: ■ ソース用ディレクトリ作成 file: path={{ item.path }} owner={{ item.owner }} group={{ item.group }} mode={{ item.mode }} state=directory with_items: - { path: "/opt/node1_usr/" , owner: node1_usr , group: node1_usr , mode: "755" } - { path: "/opt/node1_usr/.rbenv/" , owner: node1_usr , group: node1_usr , mode: "755" } - { path: "/opt/node1_usr/.rbenv/plugins/" , owner: node1_usr , group: node1_usr , mode: "755" }4.ruby依存パッケージを事前にインストール
対象rpmは以下の通り
-bison.rpm
-bzip2.rpm"
-m4.rpm
-ncurses-devel.rpm
-readline-devel.rpmバージョンは割愛。
後ほどインストールするrubyファイルもここで配布しておく。
-ruby.tar.bz2 ruby公式からダウンロード上記ファイルはまとめてrpmのフォルダに入れておく。
- name: ■ ruby RPM Copy copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - "{{ node1_rpm_cp }}" ignore_errors: "{{ ansible_check_mode }}" - name: ■ ruby RPM Install yum: name: "{{ node1_rpm_install }}" state: present ignore_errors: "{{ ansible_check_mode }}"node1_rpm_cpは配置したファイルをローカルに引っ張ってくる。
node1_rpm_installはruby依存rpmのみ先にインストールする。5.rbenvインストール
インストールといってもzipファイルを解凍するだけ。
-rbenvmaster.zip githubからダウンロード
→適当なフォルダに配置- name: ■ rbenv Source File Copy copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - "{{ rbenv_source_cp }}" ignore_errors: "{{ ansible_check_mode }}" - name: ■ rbenv Source Unzip node1_usr command: chdir=/opt/node1_usr/.rbenv/ unzip -o rbenv-master.zip ignore_errors: "{{ ansible_check_mode }}"ここは変数を入れ込むとバグるらしい、、、原因不明、、、
6.ruby_buildインストール
5同様4で配置したzipファイルを解凍するだけ。
-ruby-build-master.zip githubからダウンロード
→適当なフォルダに配置- name: ■ ruby_build Source File Copy copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - "{{ ruby_build_source_cp }}" ignore_errors: "{{ ansible_check_mode }}" - name: ■ ruby_build Source Unzip node1_usr command: chdir=/opt/node1_usr/.rbenv/plugins/ unzip -o ruby-builder-master.zip ignore_errors: "{{ ansible_check_mode }}"7.rubyに必要なファイルの配布
.bash_profile を/opt/node1_usr/に配布する。
以下の通り編集する。最後の2行が大事。# User specific environment and startup programs PATH=$PATH:$HOME/bin export PATH export PATH="/opt/node1_usr/.rbenv/rbenv-master/bin:$PATH" eval "$(rbenv init -)"8.シェルとソースのリフレッシュ
- name: ■ Shell Refresh node1_usr become: yes become_user: node1_usr shell: exec $SHELL -l ignore_errors: "{{ ansible_check_mode }}" - name: ■ .bash_profile Check Action node1_usr become: yes become_user: node1_usr shell: source ~/.bash_profile ignore_errors: "{{ ansible_check_mode }}"9.rubyインストール
必要なバージョンがインストールされているかをまず確認する。
インストールされている場合はスキップする処理、されていない場合はインストールを続行する処理とする。- name: ■ Ruby Version Check Before Install node1_usr become: yes become_user: node1_usr stat: path=/opt/node1_usr/.rbenv/versions/n.n.n register: result - name: ■ Ruby Install node1_usr become: yes become_user: node1_usr shell: bash -lc "RUBY_BUILD_CACHE_PATH=/opt/node1_usr/.rbenv/plugins/ rbenv install n.n.n" when: not result.stat.exists10.rubyバージョン切り替え
- name: ■ Ruby Version Change node1_usr become: yes become_user: node1_usr shell: bash -lc "rbenv global n.n.n" ignore_errors: "{{ ansible_check_mode }}"以上のコードはroles/middle/ruby/tasks/main.ymlに記述すること。
ハマった箇所と理由
5.rbenvインストール
コマンドを実行する箇所に変数を指定するとそんなファイル・パスはないと言われてしまう。
詳細は不明だが、絶対パスで書くのが無難。6.ruby_buildインストール
5同様の注意事項。
ファイル名が似ているため、middle_var.ymlに書くときは注意。
ずっとruby_buildのインストールにrbenv-master.zipを指定していたことに気が付くのに時間がかかったのは自分だけでいい。7.rubyに必要なファイルの配布
予め/opt/node1_usr/内に作っておくのが無難。
改行コードが問題になることがあるので、LFで統一すること。
CRLFで何時間もハマった。8.シェルとソースのリフレッシュ
そこまで大ハマりしたわけではないが、シェルとソースのリフレッシュはansibleを実行するユーザではなくrubyをインストールするユーザを指定すべき。
これを避けるためにはbecome変数を使用し、bash -lcでコマンドを実行すること。9.rubyインストール
インストール済みの場合スキップ、未インストールの場合のみインストールという処理を考えるとき、条件に悩んだ。
ruby -vでバージョンを出してもよかったが、バージョンの数値のみ取得するのが骨が折れそうだった。
rubyのインストールディレクトリ配下のversionというディレクトリの配下にバージョン名でディレクトリができることを利用し、
このディレクトリをインストールしたいバージョンの番号の有無と判定することにした。registerとwhen変数がそれである。
また、rbenv install n.n.n(バージョン名)でrubyをインストールする場合、何も指定しないとWeb上のファイルを取得しに行ってしまう。
予めダウンロード・配置しておいたファイルを使用してインストールする場合には、RUBY_BUILD_CACHE_PATH で配置先のディレクトリを指定してやる必要があった。以上の工程に3人日使ってしまい非常にもったいないことをしたので備忘録としておく。
- 投稿日:2019-10-26T00:16:30+09:00
Ubuntu 18.04 Railsインストールコマンド$ gem install rails のエラーを解決した話
目的
- Ubuntu 18.04でコマンド
$ gem install railsを実行した際に出たエラーを解決した話をまとめる。経緯
- 下記記事を参考にUbuntu18.04でRailsの環境構築をしていたところ、コマンド
$ gem install railsを実行した際にエラーが出た。
MacOS / Ubuntu で Ruby on Rails の開発環境を構築するエラー内容
- 下記にエラー内容を抜粋した内容を記載する。
$ gem install rails Building native extensions. This could take a while... ERROR: Error installing rails: ERROR: Failed to build gem native extension. current directory: /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/gems/nokogiri-1.10.4/ext/nokogiri /home/linuxbrew/.linuxbrew/opt/ruby/bin/ruby -I /home/linuxbrew/.linuxbrew/Cellar/ruby/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191025-8352-1g8if1f.rb extconf.rb checking if the C compiler accepts ... yes Building nokogiri using packaged libraries. Using mini_portile version 2.4.0 checking for gzdopen() in -lz... no zlib is missing; necessary for building libxml2 *** extconf.rb failed *** ・ ・ ・ extconf failed, exit code 1 Gem files will remain installed in /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/gems/nokogiri-1.10.4 for inspection. Results logged to /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/extensions/x86_64-linux/2.6.0/nokogiri-1.10.4/gem_make.out分析
- エラーの内容を翻訳して見た。
- どうやらzlibなるものがインストールされていないようだ。
# 翻訳前 checking for gzdopen() in -lz... no zlib is missing; necessary for building libxml2 *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary # 翻訳語 -lzでgzdopen()をチェックしています... no zlibがありません。 libxml2のビルドに必要 *** extconf.rbが失敗しました*** 何らかの理由でMakefileを作成できませんでした。おそらく必要なものがありません。解決方法
- zlibをインストールする為のコマンド
$ sudo apt-get install zlib1g-devを実行した。- 実行後再度コマンド
$ gem install railsを実行したら正常に実行された。- 下記に解決方法に至った筆者の流れを記載する。
- コマンド
$ gem install railsを実行したらエラー発生した。- コマンド
$ sudo apt-get install zlib1g-devを実行した。- コマンド
$ gem install railsが正常に実行できた。付録
- 下記に筆者がコマンド
$ gem install railsでエラーを出してから解決するまでのログを記載する。miriwo@miriwoPC:~$ gem install rails Building native extensions. This could take a while... ERROR: Error installing rails: ERROR: Failed to build gem native extension. current directory: /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/gems/nokogiri-1.10.4/ext/nokogiri /home/linuxbrew/.linuxbrew/opt/ruby/bin/ruby -I /home/linuxbrew/.linuxbrew/Cellar/ruby/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191025-8352-1g8if1f.rb extconf.rb checking if the C compiler accepts ... yes Building nokogiri using packaged libraries. Using mini_portile version 2.4.0 checking for gzdopen() in -lz... no zlib is missing; necessary for building libxml2 *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/home/linuxbrew/.linuxbrew/Cellar/ruby/2.6.5/bin/$(RUBY_BASE_NAME) --help --clean --use-system-libraries --enable-static --disable-static --with-zlib-dir --without-zlib-dir --with-zlib-include --without-zlib-include=${zlib-dir}/include --with-zlib-lib --without-zlib-lib=${zlib-dir}/lib --enable-cross-build --disable-cross-build To see why this extension failed to compile, please check the mkmf.log which can be found here: /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/extensions/x86_64-linux/2.6.0/nokogiri-1.10.4/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/gems/nokogiri-1.10.4 for inspection. Results logged to /home/linuxbrew/.linuxbrew/lib/ruby/gems/2.6.0/extensions/x86_64-linux/2.6.0/nokogiri-1.10.4/gem_make.out miriwo@miriwoPC:~$ sudo apt-get install zlib1g-dev Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libllvm7 linux-headers-4.18.0-17 linux-headers-4.18.0-17-generic linux-image-4.18.0-17-generic linux-modules-4.18.0-17-generic linux-modules-extra-4.18.0-17-generic Use 'sudo apt autoremove' to remove them. The following NEW packages will be installed: zlib1g-dev 0 upgraded, 1 newly installed, 0 to remove and 38 not upgraded. Need to get 176 kB of archives. After this operation, 457 kB of additional disk space will be used. Get:1 http://jp.archive.ubuntu.com/ubuntu bionic/main amd64 zlib1g-dev amd64 1:1.2.11.dfsg-0ubuntu2 [176 kB] Fetched 176 kB in 0s (453 kB/s) Selecting previously unselected package zlib1g-dev:amd64. (Reading database ... 225859 files and directories currently installed.) Preparing to unpack .../zlib1g-dev_1%3a1.2.11.dfsg-0ubuntu2_amd64.deb ... Unpacking zlib1g-dev:amd64 (1:1.2.11.dfsg-0ubuntu2) ... Setting up zlib1g-dev:amd64 (1:1.2.11.dfsg-0ubuntu2) ... Processing triggers for man-db (2.8.3-2ubuntu0.1) ... miriwo@miriwoPC:~$ gem install rails Building native extensions. This could take a while... Successfully installed nokogiri-1.10.4 Successfully installed crass-1.0.5 Successfully installed loofah-2.3.1 Successfully installed rails-html-sanitizer-1.3.0 Successfully installed rails-dom-testing-2.0.3 Successfully installed builder-3.2.3 Successfully installed erubi-1.9.0 Successfully installed actionview-6.0.0 Successfully installed actionpack-6.0.0 Successfully installed activemodel-6.0.0 Successfully installed activerecord-6.0.0 Successfully installed globalid-0.4.2 Successfully installed activejob-6.0.0 Successfully installed mini_mime-1.0.2 Successfully installed mail-2.7.1 Successfully installed actionmailer-6.0.0 Building native extensions. This could take a while... Successfully installed nio4r-2.5.2 Successfully installed websocket-extensions-0.1.4 Building native extensions. This could take a while... Successfully installed websocket-driver-0.7.1 Successfully installed actioncable-6.0.0 Successfully installed mimemagic-0.3.3 Successfully installed marcel-0.3.3 Successfully installed activestorage-6.0.0 Successfully installed actionmailbox-6.0.0 Successfully installed actiontext-6.0.0 Successfully installed thor-0.20.3 Successfully installed method_source-0.9.2 Successfully installed railties-6.0.0 Successfully installed sprockets-4.0.0 Successfully installed sprockets-rails-3.2.1 Successfully installed rails-6.0.0 Parsing documentation for nokogiri-1.10.4 Installing ri documentation for nokogiri-1.10.4 Parsing documentation for crass-1.0.5 Installing ri documentation for crass-1.0.5 Parsing documentation for loofah-2.3.1 Installing ri documentation for loofah-2.3.1 Parsing documentation for rails-html-sanitizer-1.3.0 Installing ri documentation for rails-html-sanitizer-1.3.0 Parsing documentation for rails-dom-testing-2.0.3 Installing ri documentation for rails-dom-testing-2.0.3 Parsing documentation for builder-3.2.3 Installing ri documentation for builder-3.2.3 Parsing documentation for erubi-1.9.0 Installing ri documentation for erubi-1.9.0 Parsing documentation for actionview-6.0.0 Installing ri documentation for actionview-6.0.0 Parsing documentation for actionpack-6.0.0 Installing ri documentation for actionpack-6.0.0 Parsing documentation for activemodel-6.0.0 Installing ri documentation for activemodel-6.0.0 Parsing documentation for activerecord-6.0.0 Installing ri documentation for activerecord-6.0.0 Parsing documentation for globalid-0.4.2 Installing ri documentation for globalid-0.4.2 Parsing documentation for activejob-6.0.0 Installing ri documentation for activejob-6.0.0 Parsing documentation for mini_mime-1.0.2 Installing ri documentation for mini_mime-1.0.2 Parsing documentation for mail-2.7.1 Installing ri documentation for mail-2.7.1 Parsing documentation for actionmailer-6.0.0 Installing ri documentation for actionmailer-6.0.0 Parsing documentation for nio4r-2.5.2 Installing ri documentation for nio4r-2.5.2 Parsing documentation for websocket-extensions-0.1.4 Installing ri documentation for websocket-extensions-0.1.4 Parsing documentation for websocket-driver-0.7.1 Installing ri documentation for websocket-driver-0.7.1 Parsing documentation for actioncable-6.0.0 Installing ri documentation for actioncable-6.0.0 Parsing documentation for mimemagic-0.3.3 Installing ri documentation for mimemagic-0.3.3 Parsing documentation for marcel-0.3.3 Installing ri documentation for marcel-0.3.3 Parsing documentation for activestorage-6.0.0 Installing ri documentation for activestorage-6.0.0 Parsing documentation for actionmailbox-6.0.0 Installing ri documentation for actionmailbox-6.0.0 Parsing documentation for actiontext-6.0.0 Installing ri documentation for actiontext-6.0.0 Parsing documentation for thor-0.20.3 Installing ri documentation for thor-0.20.3 Parsing documentation for method_source-0.9.2 Installing ri documentation for method_source-0.9.2 Parsing documentation for railties-6.0.0 Installing ri documentation for railties-6.0.0 Parsing documentation for sprockets-4.0.0 Installing ri documentation for sprockets-4.0.0 Parsing documentation for sprockets-rails-3.2.1 Installing ri documentation for sprockets-rails-3.2.1 Parsing documentation for rails-6.0.0 Installing ri documentation for rails-6.0.0 Done installing documentation for nokogiri, crass, loofah, rails-html-sanitizer, rails-dom-testing, builder, erubi, actionview, actionpack, activemodel, activerecord, globalid, activejob, mini_mime, mail, actionmailer, nio4r, websocket-extensions, websocket-driver, actioncable, mimemagic, marcel, activestorage, actionmailbox, actiontext, thor, method_source, railties, sprockets, sprockets-rails, rails after 48 seconds 31 gems installed









































