ローイングファンのプログラミング日記

ボート競技やプログラミングについて書きます

Ubuntu20.04にRuby3.0.0とPostgreSQL13をインストール - Windows10 VirtualBox Vagrant環境編

目次

環境

Windows10 Home 1909
VirtualBox 5.2.12
Vagrant 2.1.1


参考サイト

rbenv
https://github.com/rbenv

PostgreSQL APT
https://wiki.postgresql.org/wiki/Apt


rbenvを使ってRubyをインストールする

#rbenvのインストール(GitHubからcloneする場合)
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv

#echoコマンドで.bash_profileにパスを追記する
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile

#rbenvを自動で初期化するスクリプトを.bash_profileに追記する
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

#.bash_profileに追記した設定を有効化する  
$ source ~/.bash_profile

#ruby-buildをプラグインとして追加する  
#プラグイン用のディレクトリをつくる
$ mkdir -p "$(rbenv root)"/plugins

#GitHubからcloneする
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

#Rubyをインストールする
#インストール可能な最新バージョンを確認する
$ rbenv install -l

#インストール可能なすべてのバージョンを知りたい場合
$ rbenv install -L

#Rubyのインストール(かなり時間がかかる)
$ rbenv install 3.0.0

#インストールしたバージョンを使用可能にする
$ rbenv global 3.0.0

#インストールの確認
$ ruby -v
#=> ruby 3.0.0p0 (2020-12-25 revision ****) [x86_64-linux]


Rubyのバージョンアップ

#rbenvをアップグレード(最新をpull)する
$ cd ~/.rbenv
$ git pull

#ruby-buildをアップグレード(最新をpull)する
$ cd ~/.rbenv/plugins/ruby-build
$ git pull

#インストール可能な最新バージョンを確認する
$ rbenv install -l

#希望のバージョンをインストール
$ rbenv install [インストールしたいバージョン]

#バージョンの切り替え
$ rbenv global [使いたいバージョン]


PostgreSQL13をインストールする

# リポジトリキーをインポートする
$ sudo apt install curl ca-certificates gnupg
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-keyadd-

# /etc/apt/sources.list.d/pgdg.listを作成する
$ sudo sh -c'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main"> /etc/apt/sources.list.d/pgdg.list '

# パッケージリストを更新してからインストールする
$ sudo apt update
$ sudo apt install postgresql-13


PostgreSQLの起動やロケールの設定は過去の記事を参照

Ubuntu18.04にPostgreSQL10.5をインストール - ローイングファンのプログラミング日記


不具合

PostgreSQL13と一緒にpgadmin4をインストールしようとしたらエラーになった

今回はpgadmin4のインストールは諦めた。
pgadmin4なしでも今のところ特に問題はない。


pgのインストール時にエラー

Rubyアプリで使うpgをbundlerでインストールしようとしたらエラーがおきた。
エラー表示に下記の文面があったのでlibpq-devをインストールしたら解決した。

bundle installしたときのエラー表示

...
Can't find the 'libpq-fe.h header
...
An error occurred while installing pg (1.2.3),...

libpq-devをインストールで解決

$ sudo apt install libpq-dev


WSL2上のUbuntu20.04にPostgreSQL13をインストール

目次

WSL2の設定とUbuntu20.04 LTSのインストール

普段はmacOSもしくはVirtualBox Vagrant Ubuntu環境上でPostgreSQLを使っている

以前の記事

Ubuntu18.04にPostgreSQL10.5をインストール - ローイングファンのプログラミング日記


今回はWSL2環境に挑戦した

WSL2の設定は下記のガイドとおりで問題なく成功
docs.microsoft.com
Windows 10 用 Windows Subsystem for Linux のインストール ガイド
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10


UbuntuのインストールもMicrosoft Storeから問題なく成功

インストールしたUbuntuを立ち上げてユーザ名、パスワードを登録してapt upgradeまでしておく
パスワードはsudoコマンドを使うたびに必要になるので覚えておく

$ apt update
$ apt upgrade


PostgreSQLをインストール

次のページ通りにインストール

日本PostgreSQLユーザ会
ダウンロード > Linux (apt) > Apt
https://wiki.postgresql.org/wiki/Apt

# keyをインポート
$ sudo apt install curl ca-certificates gnupg
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# リストに追加(Ubuntu20.04の場合はfocal-pgdg)
$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

# アップデートしてリストに追加
$ sudo apt update

# PostgreSQLとpgadmin4をインストール
$ sudo apt install postgresql-13 pgadmin4


PostgreSQLの設定

まずインストールできたか確認

$ psql --version

> psql (PostgreSQL) 13.0 (Ubuntu 13.0-1.pgdg20.04+1)


サーバーを起動する
systemctlpg_ctlコマンドは使えなかった。別途設定が必要らしい
なのでserviceコマンドで起動

$ sudo service postgresql start
# Ubuntuユーザのpassワードを入力

> * Starting PostgreSQL 13 database server


ロールをつくっていく
まずpostgresユーザーでログインする

$ sudo -u postgres psql

> Type "help" for help.
> postgres=#


Ubuntuのユーザ名でログインできるようにする

postgres=# create role [Ubuntuのユーザ名] with login createdb;

> CREATE ROLE


postgresユーザーのパスワードを変更する  

postgres=# alter user postgres password 'postgres';

> ALTER ROLE


postgresユーザからログアウト

postgres=# \q


psqlコマンドをためす

$ psql -l

# データベースの一覧表が表示されたら成功


これでpostgresユーザにログインしなくてもpsqlコマンドが使える

操作が終わったらサーバーを停止

$ sudo service postgresql stop

> * Stopping PostgreSQL 13 database server


Visual Studio Codeの拡張

次のページ通りに設定するとWSL2のファイルが簡単に扱えるようになる

docs.microsoft.com
Windows Subsystem for LinuxVisual Studio Code の使用を開始する

https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode

Heroku 複数のアプリ間でHerokuPostgresデータベースを共有する



やったこと

Herokuの同一アカウント上で運営している2つのアプリ間でデータベースを共有した。


前提


環境変数の取得

Heroku Postgresの共有に関する解説ページはこちら。
Heroku Dev Center
Heroku Postgres
Sharing Heroku Postgres between applications
https://devcenter.heroku.com/articles/heroku-postgresql#sharing-heroku-postgres-between-applications


Herokuにログイン後、次のコマンドを入力する。

$ heroku addons:attach origin_app::DATABASE --app new_app


これで環境変数が割り当てられる。

Attaching postgresql-infinite-***** to new_app... done
Setting HEROKU_POSTGRESQL_[Color] config vars and restarting new_app... done, v***

[Color]には各々色名が入る。


Herokuアプリで接続する

割り当てられた環境変数をつかってコードを書く。

  • 割り当てられた色名を例としてBRONZEとする
  • origin_appにはusersテーブルがある
  • usersのカラム
    • id (int)
    • name (varchar)


new_app/main.rb

require 'sinatra'
require 'active_record'

class User < ActiveRecord::Base
    establish_connection(ENV['HEROKU_POSTGRESQL_BRONZE_URL'])
end

get '/' do
    # usersテーブルの全てのレコードを取得する
    user = User.new
    @users = user.all

    erb :index
end


new_app/views/index.erb

<html>
    <body>
        <ul>
            <% @users.each do |user| %> 
            <li><%= "#{user[:id]} #{user[:name]}" %></li>
            <% end %>
        </ul>
    </body>
</html>


今回の環境

Ruby 2.7.1p83
Sinatra 2.0.8
Active Record 6.0.3
pg 1.2.3


GitHubにSSH接続でpush/cloneする

目次


前提

  • macOS10.15.7上で作業
    • Linux(Ubuntu20.04)環境は別記
  • ローカルで複数のプロジェクト(ローカルリポジトリ)がある
  • GitHubアカウントは1つ
    • 同一アカウント内に複数のリポジトリを作成する/所有している
  • 既存のSSHキーはない


経緯

GitHubの2段階認証を設定したらhttps接続ができなくなった。
以下のエラーがでたときに対処した手順のメモ。

ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights

参考ページ

参考というか下記のページ通りに作業した

GitHub Docs
新しい SSH キーを生成して ssh-agent に追加する
https://docs.github.com/ja/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

GitHub Docs
GitHub アカウントへの新しい SSH キーの追加
https://docs.github.com/ja/free-pro-team@latest/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account


手順

  • SSHキーを作成する
  • configファイルに記入する(macOSのみ)
  • SSHキーをssh-agentに追加してキーチェインに保存する
  • GitHubSSHキー(公開鍵)を登録する
  • ローカルとリモートを紐づける(push時のみ)
  • push/cloneする


SSHキーを作成する


.sshディレクトリに移動する

$ cd ~/.ssh


.sshディレクトリがない場合は作成する

$ mkdir ~/.ssh

# 大事なディレクトリなので権限の設定をする
# 所有者のみ読み込み、書き込み、実行ができるように設定
$ chmod 700 ~/.ssh

# 作成したディレクトリに移動する
$ cd ~/.ssh


chmodコマンドでグループ、その他のユーザーは読み込、書き込、実行ができないディレクトリができた

chmodコマンドで参考にしたページ
chmod コマンド
https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95


keyをつくる
keyはのちのち複数つくるので任意の名前をつけておく
例として名前をid_rsa_new_fileにした

$ ssh-keygen -t rsa -b 4096 -C "[GitHubのメールアドレス]" -f id_rsa_new_file

# 確認 公開(.pub)、非公開のペアで鍵ができるはず
$ ls
#=> id_rsa_new_file  id_rsa_new_file.pub


configファイルに記入する(macOSのみLinuxではconfigファイルは不要)

configファイルをエディタで開いて以下を記入(追記)する
configファイルがない場合は作成する
~/.ssh/config

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_rsa_new_file


以後、リポジトリを増やしてキーを追加するときはIdentityFile ~/.ssh/[キー名]を追記していく。


SSHキーをssh-agentに追加してキーチェインに保存する

バックグラウンドでssh-agentを開始する

$ eval "$(ssh-agent -s)"
#=> Agent pid *****


ssh-agentに追加してキーチェインに保存
-KオプションはmacOSのみ、Linuxでは不要

$ ssh-add -K ~/.ssh/id_rsa_new_file


GitHubSSHキー(公開鍵)を登録する

公開鍵(.pub)の内容をコピーする

コマンドでコピー

$ cat ~/.ssh/id_rsa_new_file.pub | pbcopy
# または
$ pbcopy < ~/.ssh/id_rsa_new_file.pub

もしくはエディタで開いて内容をまるごとコピーする


GitHubリポジトリを作ったら/既存のリポジトリ
setting > Deploy keys > add deproy keyとすすんでコピーした公開鍵を貼り付けて登録する


ローカルとリモートを紐づける(新規pushするときのみ)


# ローカルリポジトリに移動する
$ cd [プロジェクトディレクトリ名]

# SSH接続用のアドレスを登録する
$ git remote add origin git@github.com:[アカウント名]/[リポジトリ名].git


push/cloneする

push

# 必要に応じてブランチ名を変更する
$ git branch -M main

$ git push -u origin main


clone

$ git clone git@github.com:[アカウント名]/[リポジトリ名].git


以上、-u origin mainは最初だけで以降はgit pushのみでorigin mainにpushできる


2つ目以降のリポジトリは上記の繰り返し


Sinatraのルーティングと日本語URL

Sinatraのルーティングはシンプルでわかりやすい
そのうえ複雑なことも可能
今回はデータベースのデータをもとにして複数のページをつくってみた
その際、日本語URLも試した

目次


今回の環境

仮想環境の構築、データベースのインストールと設定は過去の記事参照


ディレクトリ作成

テスト用ディレクトリ作成

routes_testというディレクトリをつくってそこへ移動

$ mkdir routes_test
$ cd routes_test


Gemのインストール

Bundlerを使って必要なGemをインストールする。
Gemfileを作成

$ bundle init


GemfileにGemを記入

gem 'sinatra'
gem 'sinatra-contrib'
gem 'activerecord'
gem 'pg'

bundleインストール

$ bundle install

アプリに必要なファイルをつくる

テンプレートはviewsディレクトリ内につくる
今回のテンプレートはErb

routes_test/main.rb
routes_test/views/index.erb
routes_test/views/club_info.erb


データベース作成

今回はPostgreSQLを使用
データベースを起動してrowingclubデータベース内にrowingclubsテーブルをつくる。

起動とデータベースの作成

$ sudo systemctl start postgresql
$ createdb rowingclub


テーブル作成のSQLファイルをつくる。

create_rowingclubs.sql

create table rowingclubs (
id  serial  primary key,
club_name varchar(20),
created_at  timestamp default current_timestamp,
updated_at  timestamp
);


rowingclubデータベースにログイン
\iコマンドでファイルからテーブルを作成する

$ psql rowingclub
rowingclub=> \i create_rowingclubs.sql


テーブルにテスト用のレコードを挿入する

まずレコード挿入用のSQLファイルをつくる。

insert_record_to_rowingclub.sql

insert into rowingclubs (club_name) values
('ローイングクラブ'),
('ボートクラブ'),
('漕艇倶楽部'),
('端艇倶楽部');


\iコマンドでファイルからレコードを挿入する
挿入後にテーブルからログアウト

rowingclub=> \i insert_record_to_rowingclub.sql
rowingclub=> \q


できあがったテーブルの内容
rowingclub/rowingclubs

id club_name
1 ローイングクラブ
2 ボートクラブ
3 漕艇倶楽部
4 端艇倶楽部


コーディング

main.rb

require 'sinatra'
require 'sinatra/reloader'
require 'active_record'

#モデルの作成
class Rowingclub < ActiveRecord::Base
    establish_connection(
        adapter:  'postgresql',
        host:     "",
        username: 'vagrant',
        password: "",
        database: 'rowingclub'
    )

    def allclub
        allclub = Rowingclub.all
        return allclub
    end
end

#モデルの初期化と全レコードの抽出
allclub = Rowingclub.new.allclub

#ルーティング
#トップページ
get '/' do
    @allclub = allclub
    erb :index
end

#モデルからeachメソッドでレコードを取り出して
#各々のルートを作成
allclub.each do |club|
    #idのURLを作成
    get "/#{club['id']}" do
        @club_name = club['club_name']
        erb :club_info
    end
    
    #日本語のURLを作成
    get "/#{club['club_name']}" do
        @club_name = club['club_name']
        erb :club_info
    end
end


index.erb

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html" charset="utf-8">
        <title>トップページ | Sinatra ルーティングテスト</title>
    </head>
    <body>
        <p>idでURLを作成</p>
        <ul>
        <% @allclub.each do |club| %>
            <li><a href=<%= "/#{club['id']}" %> ><%= "#{club['id']}" %></a></li>
        <% end %>
        </ul>
        <hr>
        <p>club_name(日本語)でURLを作成</p>
        <ul>
        <% @allclub.each do |club| %>
            <li><a href=<%= "/#{club['club_name']}" %> ><%= "#{club['club_name']}" %></a></li>
        <% end %>
        </ul>
    </body>
</html>


club_info.erb

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html" charset="utf-8">
        <title>クラブ紹介ページ | Sinatra ルーティングテスト</title>
    </head>
    <body>
        <h1><%= "#{@club_name}の紹介ページ" %></h1>
    </body>
</html>


実行する

$ ruby main.rb -o [ipアドレス]

WEBrickが立ち上がったらブラウで表示させる
ブラウザにipアドレスとポート番号を入力する
http://[ipアドレス]:4567
これでトップページが表示されれば成功

f:id:rowingfan:20190630150148p:plain
index.erb


リンクをたどってページ遷移を確認
id(半角数字)のURL

f:id:rowingfan:20190630150553p:plain
URLのPathがid(半角数字)になっている


日本語のURL

f:id:rowingfan:20190630150728p:plain
URLのPathがclub_name(日本語)になっている


どちらもURLが期待通りになっている

URLエンコード

本来URLには非ASCII文字は使えないらしい
上で試したような場合はブラウザが日本語のURLをエンコードしてくれているのでエラーにならない
しかしredirectさせたりする場合は事前にURLエンコードが必要になる
URLエンコードするにはCGI.escapeメソッドを使う

CGI.escapeの使い方

require 'cgi'

CGI.escape '変換したい文字列'


エラーになる例

redirect "/漕艇倶楽部"

#=> ERROR URI::InvalidURIError: URI must be ascii only


URLエンコードをした例

require 'cgi'

ja_url = "/漕艇倶楽部"
ascii_url = CGI.escape ja_url
redirect "#{ascii_url}"
#=>エラーなくredirectする


参考ページ

Sinatra README
Routes
http://sinatrarb.com/intro.html

Rubyリファレンスマニュアル
CGIクラス
https://docs.ruby-lang.org/ja/latest/method/CGI/s/escape.html

JavaScriptの基礎 細かな注意点

JavaScriptを勉強中。
気づいたことを随時追加する予定。

目次


前置演算と後置演算の違い

インクリメント/デクリメントの結果を別名の変数に代入したいときは前置演算をつかう

例: 前置インクリメント

let x = 5;
let y = ++x;
console.log(x); // =>6
console.log(y); // =>6


例: 後置インクリメント

let x = 5;
let y = x++;
console.log(x); // =>6
console.log(y); // =>5


例の解説
xの演算結果は前置と後置で同じ。
xを更に別の変数へ代入する時に違いが出る。
前置の場合は演算したあとに変数へ代入。
後置の場合は演算する前に代入、その後に演算する。

浮動小数点数値を含む計算

JavaScript内では2進数で演算を行うため10進数と違う結果になるときがある。

例: (0.2 * 3)が0.6にならない

console.log(0.2 * 3); //=> 0.6000000000000001
console.log(0.2 * 3 === 0.6); //=> false


解決策
演算する前に浮動小数点数値を整数値にして演算後に桁数を戻す。
小数点以下1桁の場合は10を掛けてから演算した後に10で割って桁を戻す。

例: 解決策

console.log(((0.2 * 10) * 3) / 10); //=> 0.6
console.log(((0.2 * 10) * 3) / 10 === 0.6); //=> true


暗黙的なfalse

JavaScriptでは空文字列(''や"")と数値の0は条件判断のときに偽と判定される。
(Rubyの場合はnilとfalse以外は真なので、空文字列や0は真になる。)

JavaScriptで偽となる値

  • 空文字列 ("", '')
  • 0 (数値)、NaN
  • null、undefined


例: 空文字列と0を使った条件分岐

let str = '', num = 0;
str ? console.log('空文字はtrue') : console.log('空文字はfalse'); //=> 空文字はfalse
num ? console.log('0はtrue') : console.log('0はfalse'); //=> 0はfalse


WSL(Windows Subsystem for Linux)のUbuntuからWindows上のファイルを参照する

目次


前提

  • WSLが有効化されていてUbuntuがインストールされている
  • Ubuntu内にRubyがインストールされている


Windows内のファイルをUbuntuから参照する

Windows PowerShellでHomeディレクトリにMyUbuntuディレクトリをつくる。

> mkdir MyUbuntu


Ubuntuを起動して(Ubuntuのターミナルを立ち上げて)さきほどつくったディレクトリを参照する。

lsコマンドを使う

$ ls /mnt/c/Users/username

※usernameは各自のユーザ名

username内にMyUbuntuディレクトリがみつかる。

移動するにはcdコマンドを使う。

$ cd /mnt/c/Users/username/MyUbuntu


Windows上でRubyのコードを書いてUbuntu上で実行する

さきほどつくったMyUbuntuディレクトリ内にRubyファイルを保存する。

C:\Users\username\MyUbuntu\hello_ubuntu.rb

puts 'Hello Ubuntu'


Ubuntu上で実行する。
Ubuntuを起動してMyUbuntuに移動する。

$ cd /mnt/c/Users/username/MyUbuntu


rubyコマンドでコードを実行する。

$ ruby hello_ubuntu.rb

#=> Hello Ubuntu


WSLのUbuntuRubyを使えた。
Windowsマシンでの開発が楽になる。

今回の環境

Windows10 1803
Ubuntu 16.04
Ruby 2.5.3p105