gensym

プログラミングと読書、勉強に関するメモ

ルーティングで文字列をモデルのパスに使用する[Rails]

rails で resources を使うと自動でパスと関連したメソッドが作られる。
例えば name 要素を持つ User モデルを作ったとして、

# config/routes.rb
...
  resources :users
...

のようにすると、id が 1 の User のパスは、
www.example.com/users/1
のようになる。
これは分かりやすくて良いのだけれど、少々不格好でスクレイピングのコントロールもしにくい。
理想としては
www.example.com/example_user
のように、モデル名を無くして、ユーザ名でアクセス出来るようにしたい。
有名どころだと TwitterGithub はこのようにしているようだ。

まずは routes.rb を書き換える。

# config/routes.rb
...
  get '/:id', to: 'users#show'
...

デフォルトの id は整数なので、to_param メソッドをオーバーライドして name を使うようにする。

# app/model/user.rb
...
  def to_param
    name
  end
...

user_path メソッドもオーバーライドする。

# app/helper/application_helper.rb
...
  def user_path(user)
    "/#{user.name}"
  end
...

test を使うときは test_helper でもオーバーライドする必要があるだろう。
とりあえず show だけだが、edit や destroy も同様に出来る。
文字列をパスに使う場合は一意性が必要になるので、インデックスは必須だ。
また、デフォルトの id を使う場合に比べて検索のパフォーマンスも低下するだろう。

Ruby の管理に rbenv を導入する

環境: macOS Sierra, Ubuntu 16.04

rbenv は ruby のバージョン管理ソフトで、変化の速い ruby 界隈では必須と言えるだろう。
まずはインストール。

brew install rbenv

このままだとパスが通っていないので、.bash_profile に追加する。

# .bash_profile
export PATH="$HOME/.rbenv/shims:$PATH"
# バージョン一覧
rbenv install -l
# バージョンを指定してインストール
rbenv install 2.4.0
# global で使うバージョンを指定する
rbenv global 2.4.0
ruby -v

でバージョンを確認して、問題なし。
参考 : http://qiita.com/Chrowa3/items/34904262f7589a60aead

  • 追記- 17/2/4

Ubuntu だと若干違う

sudo aptitude install rbenv

で rbenv をインストールできるが、このままだと ruby のインストールリストは空っぽだ。

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

ruby-build をインストールすると、一覧が得られる。
あとは Mac と同様に

rbenv install 2.4.0

から設定できる。

参考:
https://github.com/rbenv/ruby-build

Webサイトを作ったときの評価ツール

web サイトを作ったときに、効率的なレスポンスやセキュリティ、SEO などがきちんと出来ているかを調べるツール。

PageSpeed Insights
アクセスする際の効率性を調べてくれる。
リクエスト最適化やファイルの圧縮、キャッシュの利用などが出来ているか。

SSL Server Test (Powered by Qualys SSL Labs)
セキュリティをチェック。
最高スコアにするのは結構大変。
nginx ならばここが参考になる。
NginxでHTTPS : ゼロから始めてSSLの評価をA+にするまで Part 1 | インフラ・ミドルウェア | POSTD

Website Grader
パフォーマンスやセキュリティ、SEO 全て調べてくれるが、上記のサイトに比べて評価が甘め。

どのサイトもアドレスを入力するだけでよく手軽で、改善方法もある程度教えてくれる。

Bitcoin-Core のブロックサイズを削減する

Bitcoin のデフォルトウォレットである Bitcoin-Core はフルノードのウォレットで、ブロックチェーンのサイズは永遠に増え続ける。参考: ビットコインチャート - Blockchain.info
ナカモト論文にもあった pruning (枝刈) 機能が実装されていたので使ってみる。
参考:Bitcoin Core version 0.12.0 released, Running Bitcoin - Bitcoin Wiki
bitcoin ディレクトリ内部の conf ファイルに書き加える。

# bitcoin.conf
# ...
prune=20000 # ブロックの保存容量、MB 単位、 550 以上

上の場合20 GB を超えたブロックは古い方から削除される。
当然大きいほど安全になる。
削除されたブロックは参照できないので、外部からウォレットやアドレスをインポートすることは出来なくなる。

クラウドにサーバを立てた時の ssh, ufw の設定[Ubuntu]

環境: ubuntu 16.04

AWSVPS サービスでクラウドサーバを立てた時に安全に使うための一連の流れ。

まずは root でリモートにログイン。
パスワードか公開鍵かはサービスによる。

ssh root@example.com

普段使うユーザを作成する。基本的にこれ以降 root は使わない。
ユーザ名をローカルとそろえておくと一々名前を指定しなくてもよくなる。
パスワード以外は空でも良い。

adduser username

作成したユーザに sudo 権限を付与

gpasswd -a username sudo

一度ログアウトし、作成したユーザでログイン

logout
ssh example.com

ログインできることと、 sudo 権限を確認。

sudo aptitude update
sudo aptitude upgrade

ユーザのホームディレクトリに ssh 用のフォルダを作成。

mkdir .ssh

.ssh/authorized_keys
にローカルの cat .ssh/id_rsa.pub の内容をコピペ。
ログアウトし、パスワード無しでログイン出来ることを確認。
ssh の設定ファイルを書き換える。

# /etc/ssh/sshd_conf
PasswordAuthentication no
# パスワード認証を禁止
UsePAM no
# PAM の使用を禁止
PermitRootLogin no
# root へのログインを禁止

ssh やその他アップグレードの設定を反映させるため再起動する。

sudo reboot

一応 root ではじかれるかチェック

ssh root@example.com
# -> Permission denied (publickey).

ssh 設定はここまで。
ポートは基本的に ssh だけ開けておき、それ以外は使う都度に開けておくのがよい。

sudo ufw enable
# アクティブ化
sudo ufw default DENY
# デフォルトは拒否
sudo ufw allow 22
# ssh を許可
sudo ufw status
# 設定を確認
sudo ufw reload
# 設定を反映

一応ローカルからおかしなポートがあいていないか確認。

nmap -Pn example.com

参考

force_ssl = true 時のリダイレクトループ [Rails]

環境 ubuntu: 16.04, rails: 4.2.6, nginx: 1.4.6

Rails において https 通信を強制するには config/environments/production.rb 中の config.force_ssl = true をコメントアウトすればいいが、nginx でも https 転送の設定をしているとリダイレクトの無限ループに陥ってしまう。
nginx だけでも良いのだけれど、リンクやリダイレクトなどの rails 内部の処理が http で処理されるため、それらもいちいち nginx でリダイレクトするのがうっとうしいし、ログも肥大化する。
nginx の設定ファイルを書き換えることで対処できる。
参考: Nginx + SSL + Rails -- BONNOH FRACTION 14
パスは私の環境に依っている。

# /etc/nginx/conf.d/rails.conf
server {

# ...

location @unicorn {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;

  # この行を追加
  proxy_set_header X-FORWARDED_PROTO https;

  proxy_pass http://unicorn;
}

rails と nginx を再起動して、反映させる。

メタプログラミングRuby まとめ [学習メモ]

メタプログラミングRuby 第2版

メタプログラミングRuby 第2版

本書は ruby におけるメタプログラミングを扱った本で、ruby と言うことをのぞいても貴重なメタプログラミングの資料だ。
メタプログラミングとは「プログラムを書くプログラム」を書くプログラミング手法のことで、有名なところでLisp 族におけるマクロがある。
Lisp におけるメタプログラミングの教科書が「On Lisp」ならば、この本は ruby での最右翼だろう。
高級感のある表紙と厚くない分量はやる気をそぐことがない。
文章も対話形式で読みやすく、しばしば挟まれるクイズも技量の定着に一役買う。
メタプログラミング、と題名にはあるが、lisp におけるメタプログラミングがマクロではっきりと区切られているのに対して ruby においてその境界ははしばしば曖昧だ。
ruby におけるダイナミックなコーディング法を細かく解説してあり、全く新しい方法を学ぶ、というよりもこれまで曖昧だった ruby の深い仕組みへの理解を助けられたように思う。
これまで私は ruby は一部の人間が行き当たりばったりに仕様を決めた、使いやすいが安っぽい rails 用言語、のようなイメージがあったところだが、本書を読んで実は一貫した仕組みを備えている精緻な言語ことが分かってきたように感じる。

内容にあった動的なメソッド定義やスコープの切り替えなどはよく使うようになった。
しかし、多くの内容はいくらかの思考の飛躍が必要で、意識的に使おうとしないと永遠に使うことはないだろう。
本書は非常に難解と言うわけではないが、初心者向けでもないし、実際の所主人公のボブのように一週間で終えるのも難しいだろう。
完全に物にするには本棚に置いて何度か読み返す必要があり、またその価値がある。
背表紙も美しいので、見栄えも悪くない。

本書で書かれているメタプログラミングを使う究極の目的はコードの重複を極限まで削ることにあるのだろうと思う。
コードが短く、抽象的に、高密度になればバグの頻度が下がり、読みやすくなり、何より、楽しい。
それは ruby 自体が目指すものと近いのかもしれない。

sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp
sym.hateblo.jp