authlogic で blank の password で update 出来てしまう問題
イントロ
情報が古いけど
改めてまとめると、以下の様な状態。
authlogic
でログインユーザーを作成- ログインユーザーは
password
を form に入力する
- ログインユーザーは
- ログインユーザーを編集する画面を作る
- 新規作成ではないので注意
password
を編集可能にする
- ログインユーザーを編集するとき、パスワードを空にして保存できてしまう
validates_length_of
は何も設定しないなら 4 文字が minimum なので、空で保存できるのはおかしい- https://github.com/binarylogic/authlogic/blob/23751e3eaba4c2b09751505079d7264fd1cc8b72/lib/authlogic/acts_as_authentic/password.rb#L95
解決法
class User < ActiveRecord::Base acts_as_authentic do |c| c.ignore_password_blank = false end end
とする。
よく見ると
のコメントに書いてある。
前提条件も含めて説明すると...
- 編集画面において、
password
を最初から入力済みにすることはできない- DB に保存されている
password
を復号することはできないため(暗号化方式によるが) - つまり編集画面を開いた直後はどうしても空になってしまう
- DB に保存されている
- 状況として「
password
は変えたくないけど、ページを遷移してしまう」ケースが存在するだろう- どういうケースかは明記されてないけど、例えば間違って「更新」ボタンを押してしまったりするとか?
- そうすると、空のパスワードが保存されてしまい、セキュリティ的に甘くなる
- そういうケースは避けたい
- オプションで変更できる
ということらしい。(多分)
Capybara::Poltergeist で remote debug が動かない件
イントロ
タイトルの通り。Capybara::Poltergest
の目玉機能である remote debugging
がうまく動作しなくて、色々試行錯誤した話。
https://github.com/teampoltergeist/poltergeist#remote-debugging-experimental
環境
OSX 10.10.3
phantomjs 2.2.0
poltergeist 1.6.0
chromium 45.0.2411.0
remote debugging とは
poltergeist
の README に書いてあるとおり
Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, js_errors: false, inspector: true) end @session = Capybara::Session.new(:poltergeist) @session.visit url @session.driver.debug
のような感じで、driver.debug のタイミングでブラウザを起動し、debug できる機能らしい。
使い方は簡単で
Capybara::Poltergeist::Driver.new
にinspector: true
オプションを渡すdriver.debug
を呼ぶ
だけで良い。
苦戦した所
1. そもそもブラウザ起動しない
# @session.driver.debug を使った spec を実行させる bundle exec rspec ... Poltergeist execution paused. Press enter to continue. The file //localhost:9664 does not exist.
てっきり chrome
か何かが自動で起動するんだろうなぁと思ってたが、file //localhost:9664
がないと言われて怒られてしまう。
解決法
微妙なアプローチだけど、chromium
を install して回避してみた。
brew install Caskroom/cask/chromium
ln -s /opt/homebrew-cask/Caskroom/chromium/latest/chrome-mac/Chromium.app/Contents/MacOS/Chromium /usr/local/bin/chromium
として、chromium コマンドをむりやり PATH
に追加。
これだけで良い。
というのも、ブラウザ起動の仕組みは単純で、
chromium chromium-browser google-chrome
のいずれかのコマンドが PATH に通ってれば実行される、というものだから。
chromium http://www.google.co.jp
と叩いて chromium
が起動して google
トップページが表示されるならOKなはず。
google-chrome
コマンドがどうやら linux 環境でのコマンドというのと、mac で google-chrome
コマンドに相当するものを見つけられなかったので、こんな感じになりました。
Check failed: feature. と言われて起動できない。
ところが上記をやっても解決しない。
chromium
が動こうとするのだが、以下の様なエラーが出て、chromium
が起動できない。
Poltergeist execution paused. Press enter to continue. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:ERROR:component_loader.cc(154)] Failed to parse extension manifest. [86324:1299:0524/032749:FATAL:feature_provider.cc(75)] Check failed: feature. FeatureProvider 'behavior' does not contain Feature 'whitelisted_for_incognito'
色々調べてみたがよくわからない。
chromium
のソースコードにそれっぽいものを発見して、右往左往したけど挫折。
解決法
これは 予め chromium を起動した状態で、@session.driver.debug を実行する と回避できる。
要するに chromium
起動させて rspec 叩くわけです。
すると
のように file:///localhost:9664
を開こうとしているから、file:///
を消してエンター。
URL があらわれた。URL をクリック。
無事コンソール画面へ
まとめ
溢れんばかりのバッドノウハウ感。
poltergiest
の experimental な feature なので、参考になれば。
google-chrome
使うことができれば、妙なエラーはでない?のかもしれない。
みんなどうやってるの...
bootstrap-generators で bootstrap 導入後、一部の flash が使えなくなる現象
イントロ
bootstrap 導入すると、flash がちゃんと動かなくなって戸惑うやつ。
decioferreira/bootstrap-generators で生成する flash 部分にミスがあるのが原因(多分)
具体的には flash[:alert]
時でも、緑枠の flash メッセージになってしまう現象。
ちゃんと考えると直せるんだけど、思い出すのが面倒なので残す。
環境
rails 4.2.1
sass-rails 5.0.3
bootstrap-sass 3.3.4
bootstrap-generators 3.3.1
各 gem の install 方法なども省略。 README.md
の通りです。
bootstrap-generators について
意外とスター数が少ないので補足。
rails で twitter-bootstrap 導入しようとすると、有名なのは以下の2つ。
- seyhunak/twitter-bootstrap-rails
LESS
- generator 付き
- install 面倒 (随分前の記憶だけど)
- 有志が作ってる?
- twbs/bootstrap-sass
sass(scss)
- generator 付いてない
- install 簡単
- 公式(
Official Sass port of Bootstrap
)
bootstrap-sass
のほうが簡単に導入できるが、generator が付いていないので、view 等が手作りになってしまう。
一方で twitter-bootstrap-rails
は導入が面倒だが、generator が便利で、一回インストールできてしまえば楽になってくる、という感じ。
正に一長一短な2つの gem なわけですが、実は boostrap の generator は gem になって切りだされていて、bootstrap-sass
と合わせることで「install 簡単」と「generator」のイイトコロ取りをできるわけです。
その generator が decioferreira/bootstrap-generators です。
rails generate bootstrap:install
これで bootstrap のあの黒いヘッダー(やそれ以外も)が生成されます。
haml/slim/erb
に対応している。
直し方
app/views/layouts/application.html.erb
(bootstrap 導入後)
の class を作っている部分を直す。
<% flash.each do |name, msg| %> - <%= content_tag :div, :class => "alert alert-#{ name == :error ? "danger" : "success" } alert-dismissable", :role => "alert" do + <%= content_tag :div, :class => "alert alert-#{ name == "alert" ? "danger" : "success" } alert-dismissable", :role => "alert" do <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <%= msg %> <% end %> <% end %>
後はいつもどおり flash[:alert]
してあげればよい。
if @user_session.save redirect_to root_url, notice: "Login successful" else redirect_to login_url, alert: 'Login failed.' end
何も考えず redirect_to login_url, error: 'Login failed.'
みたいにやっても効かないので注意。
(view で :error
とあるから引っかかった。)
参考
おまけ
記述量を最小限にして直すと、上記のようになるけど、いやちゃんと考えたい、という場合には以下が参考になる。
以下の 3 つのうち、どれかを使えばひとまずは大丈夫そう。
(要は flash のキーが bootstrap のクラスに対応していればいいだけなので)
heroku で Postgres 9.4 を使う
イントロ
タイトルの通り。jsonb 型のカラムを取り扱おうとしたら、激しく怒られた。
rake aborted! StandardError: An error has occurred, this and all later migrations canceled: ... PG::UndefinedObject: ERROR: type "jsonb" does not exist LINE 1: SELECT 'jsonb'::regtype::oid ... : SELECT 'jsonb'::regtype::oid/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec' ...
原因
Postgres の default version が 9.3
だから。jsonb
型は 9.4
からサポートされているので、そんな型しらねーよと言われている。
https://devcenter.heroku.com/articles/heroku-postgresql#version-support-and-legacy-infrastructure
解決法
https://blog.heroku.com/archives/2015/1/8/postgres-9-4-on-heroku
9.4 に upgrade して、DATABASE_URL
を切り替えるだけでよい。
% heroku addons:add heroku-postgresql --version=9.4 --app test Adding heroku-postgresql on test... done, v14 (free) Attached as HEROKU_POSTGRESQL_YELLOW_URL Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pgbackups:restore. Use `heroku addons:docs heroku-postgresql` to view documentation.
config:unset
% heroku config:unset DATABASE_URL --app test Unsetting DATABASE_URL and restarting test... done, v15
config:set
% heroku config --app test === test Config Vars .... HEROKU_POSTGRESQL_ROSE_URL: postgres://xxxxx HEROKU_POSTGRESQL_YELLOW_URL: postgres://yyyyy ....
upgrade した時のログにも書いてあった通りで、HEROKU_POSTGRESQL_YELLOW_URL
という環境変数が attach されているので、この value を DATABASE_URL に set する。
heroku config:set DATABASE_URL=postgres://yyyy
再起動
migration して再起動して反映させる。
heroku run rake db:migrate --app test heroku run rake db:seed --app test heroku restart --app test
rails で id を BIGINT 型 + primary key + AUTO_INCREMENT する
イントロ
rails のモデルは自動で id というカラムを作ってくれますが、これは常に INT 型。
BIGINT
型にしようとしたら、結構ハマったのでメモする。
使っている database はmysql
です。
(postgresql
だとこの罠は回避できるのだろうか?)
tl;dr
- 普通に頑張ると...
db:migrate
とdb:setup
の実行結果が異なる- migration ファイルの内容が、
schema.rb
に(一部)反映されないため
- migration ファイルの内容が、
db:migrate
とdb:setup
の実行結果が異なると、db:rollback
ができなくなるので、辛くなりそう。db:migrate
かdb:setup
どちらかを使わない、という運用方式もある- だが、面倒くさいので、そういうことを意識したくない
- 解決方法は 2 つ
format_schema = :sql
- kamipo/activerecord-mysql-awesome を使う
普通にやってみる
Rails探訪 ~ create_table 編 ~ | マネーフォワード エンジニアブログ の素晴らしい参考記事によると、こんな感じ。
(ところで参考記事を見ると、色々地雷を踏み抜いてこの結論なので、この時点で既に普通でない気もする)
class CreateUsers < ActiveRecord::Migration def change create_table :users, id: false do |t| t.column :id, 'BIGINT PRIMARY KEY AUTO_INCREMENT' t.string :name t.timestamps null: false end end end
rake db:migrate
% rake db:drop db:create db:migrate
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
無事成功。
rake db:setup
一見うまくいってそうだが、実はこれは問題がある。
db/scheme.rb
に BIGINT
型にしたよ、という内容が反映されていないために、db:setup
をやると db:migrate
の結果と異なったものになってしまう。
% rake db:setup
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.01 sec)
INT型
に戻ってしまった。
じゃあどうするの?と言うと、schema_format = :sql
方式か activerecord-mysql-awesome
方式の二通りがある。
schema_format = :sql
よく見かける解決法。
デフォルトでは schema_format
は ruby なので、これを sql にする。
:ruby
では db/schema.rb
を生成するが、:sql
にすると db/structure.sql
を生成してくれる。
config/application.rb
等に予め設定しておく。
config.active_record.schema_format = :sql
rake db:migrate
migration ファイルはここと同じものを使う。
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.01 sec)
bigint 型になっている。ここまでは良い
rake db:setup
% rake db:setup
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
今度は migrate
と setup
の結果が同じになりました。
activerecord-mysql-awesome
kamipo/activerecord-mysql-awesome
を使う。
この場合 schema_format
は :ruby
のままで良い。
class CreateUsers < ActiveRecord::Migration def change create_table :users, id: :bigint do |t| t.string :name t.timestamps null: false end end end
のような migration ファイルを作る
rake db:migrate
% rake db:drop db:create db:migrate
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
rake db:setup
% rake db:setup
mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
migrate
と setup
の結果が同じになった。
change_column 編
create_table
ではなく、change_column
でやったらどうなるか。
create_table
の時点で INT
を BIGINT
にしようと思うことが少ないので、実は change_column
で対応できるかどうかが重要。
create_table
の時と違って、今度は db:rollback
が成功するかどうかもチェックしなければならない。
activerecord-mysql-awesome / schema_format = :sql
sql の確認コマンドは鬱陶しいので省略。
class ChangeIdColumnToUsers < ActiveRecord::Migration def change reversible do |dir| dir.up do change_column :users, :id, :bigint, auto_increment: true end dir.down do change_column :users, :id, :int, auto_increment: true end end end end
この migration ファイルで
rake db:drop db:create db:migrate
rake db:setup
rake db:rollback
が成功する。ばっちり。
activerecord-mysql-awesome
でも schema_format = :sql
でも同じ結果になったので、change_column
の時はこうすれば良さそう。
普通にやる
勿論これも activerecord-mysql-awesome
か schema_format = :sql
をせずに migration しても、 db:setup
で id が INT型
になってしまう。
おまけ
https://github.com/rails/rails/pull/18220 がマージされているので、現時点での rails の master では対応済みのよう。
なので、 第三の選択「もうしばらく待つ」 も有りかも。
少なくとも Rails 4.2.1
では修正は含まれていなかったです。
ubuntu で install 済みのパッケージリストを表示する
イントロ
yum list installed
的なやつ。
apt-get list
のようなコマンドがあるだろうと思っていたが無かった。
コマンド
dpkg --get-selections
参考
http://www.howtogeek.com/howto/linux/show-the-list-of-installed-packages-on-ubuntu-or-debian/
embulk-filter-eval というフィルタープラグイン書いた
イントロ
まぁ半分ネタも入ってますが、何かちょっとした事を行う程度なら役に立つはず。
これは何が便利?
input
として与えられたカラムに対して、Ruby のコードでちょっとした変換を加える事ができる embulk プラグインです。
embulk
の version 0.5.2
で作りました。
example
github の README に書いてあるサンプルそのままなのですが。(サボってるわけじゃなくて、何かサンプルがあったほうが説明しやすい)
以下のように embulk
コマンドを使って sample を作り、preview できたとします。
$ embulk example $ embulk guess embulk-example/example.yml -o config.yml
preview
すると、以下の様な出力です。
$ embulk preview config.yml +---------+--------------+-------------------------+-------------------------+----------------------------+ | id:long | account:long | time:timestamp | purchase:timestamp | comment:string | +---------+--------------+-------------------------+-------------------------+----------------------------+ | 1 | 32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC | embulk | | 2 | 14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC | embulk jruby | | 3 | 27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin | | 4 | 11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC | NULL | +---------+--------------+-------------------------+-------------------------+----------------------------+
eval_columns
では、例えば全ての id に 1
を足して出力したい、という要望があったとします。
こんな時に filter-eval
では簡単に書くことが出来ます。 config.yml
に以下のように指定するだけ。
filters: - type: eval eval_columns: - id: value + 1
value
には id 列の要素が入ってきます。
なので value + 1
とすると、最初は value =1 なので、 value + 1
が評価されて 2 が返って、次は 3 が返って... というわけです。
$ embulk preview config.yml +---------+--------------+-------------------------+-------------------------+----------------------------+ | id:long | account:long | time:timestamp | purchase:timestamp | comment:string | +---------+--------------+-------------------------+-------------------------+----------------------------+ | 2 | 32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC | embulk | | 3 | 14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC | embulk jruby | | 4 | 27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin | | 5 | 11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC | NULL | +---------+--------------+-------------------------+-------------------------+----------------------------+
実行してみたら、id のカラムが 2, 3, 4, 5
となりました。
out_columns
このプラグインでは出力したいカラムを制御することも可能で、out_columns
という設定で、出力したいカラムを配列で書けば可能です。
filters: - type: eval eval_columns: - id: value + 1 out_columns: - id
これは out_columns
に id
しか指定していないので
$ embulk preview config.yml +---------+ | id:long | +---------+ | 2 | | 3 | | 4 | | 5 | +---------+
こんな感じになります。
まとめ
またゴミのような gem を作ってしまった...
次はもっといいものを考えてます。
rbenv の plugins
イントロ
今使ってる rbenv
の plugin
たち。
rbenv
はこういうエコシステムが便利だから使い続けている。
最近務めている会社では流行りのようなので、私もやってみる。
plugins
% l .rbenv/plugins/ rbenv-ctags rbenv-default-gems rbenv-gemset rbenv-update ruby-build
順に紹介
rbenv-ctags
ruby のコアライブラリにタグファイル(ctags
用)を作ってくれるやつ。
ruby のコアライブラリを追うときに便利。だが、これは vim 用のタグしか吐いてくれない。(作者が vim 使いだから?)
vim 使える人は本家を使えばいいのだけど、私は emacs
しか使えないので、emacs
用のタグを吐くように、fork したものを使ってる。
PR 出すと vim マッチョな作者に殺されそうなのでしていない。
rbenv-default-gems
sstephenson/rbenv-default-gems
rbenv build
を使って ruby を install した時に、自動で gem を install してくれるやつ。
一回入れてしまうと便利。有名。
少し変わったことといえば、mgi166/dotfiles で default-gems
ファイルをバージョン管理していて
rake install default-gems
で ~/.rbenv/default-gems
ディレクトリにシンボリックリンクを貼ってくれるようにしたが、このメソッド、全く流行る気がしない。
% cat ~/.rbenv/default-gems bundler pry pry-byebug pry-stack_explorer ripper-tags
デフォルトの環境汚したくないけど、汚しまくっていて、羞恥心がなくなりつつある今日この頃。
rbenv-gemset
一言で言うと rbenv
版 rvm gemset
gem を管理するやつ。bundler
はプロジェクト単位で管理するけど、これは自在に namespace を作ることができる。
昔は gem 作るたびに gemset
作ってた。Gemfile
作るのめんどいけど、何か作ろうかなーって時に使う。
最近は何かやる際には gem
にするつもりがなくても bundle gem
や bundle init
で頑張る場合が多く、出番が少ない。
あ、でも rails
っていう gemset 作っておくと、rails new
する時楽で好き。
ruby-build
のように、.rbenv-gemsets
ファイルの有無で gemset
が決まるので、bundler
と共存する道はある、と思ってる。
% rbenv gemset list 1.9.3-p545: chef_repo veewee-boxes 2.1.0: d_parallel hipchat_searcher 2.1.2: dangerous_open_uri hipchat_searcher qiita-notify rails s3_utils 2.1.5: rails 2.2.1: rails 2.3.0-dev: rails
rbenv-update
rbenv update
コマンドで、全ての plugin を git pull
してくれるやつ。
これのお陰で ruby の新しいバージョンが出るたびに、毎回
cd ~/.rbenv/plugins/ruby-build
git pull
しなくてよくなった。 コマンド覚えやすいから好き。
ruby-build
rbenv-build
じゃなくて、ruby-build
rbenv
を有名にした MVP
。(と思っている)
説明不要。
まとめ
ネタになると思ったけど、有名どころしか使ってない。
boot2docker 内のコンテナに ssh で接続する
イントロ
最近ようやく docker を触り始めています。
にわか丸出しなので、【翻訳】Dockerコンテナ内でSSHDを実行してはいけない理由 | POSTD のような記事を見かけたのにも関わらず、ssh で接続しようとしています。
理由は serverspec
使ってコンテナのテストしたいと考えたからです。
(ssh
接続しないとできない... はず)
方法
Dockerfile
FROM ubuntu:14.04 RUN apt-get update RUN apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:root' | chpasswd RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config EXPOSE 22 CMD /usr/sbin/sshd -D
build
% docker build -t sshd . % docker port $(docker run -d -P openssh) 22 #=> 0.0.0.0:49155 % docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d215294c5cf sshd:latest "/bin/sh -c '/usr/sb 17 seconds ago Up 16 seconds 0.0.0.0:49155->22/tcp boring_hodgkin
無事コンテナが作れた。
docker run
に -P
オプションを渡さないと expose
された port が公開されないらしく、若干ハマった。(https://docs.docker.com/reference/run/#expose-incoming-ports)
docker port
コマンド実行結果の port 部分を覚えておく。
接続してみる
-p
の引数は先ほどメモった docker port
コマンド実行結果を渡す。
% ssh root@$(boot2docker ip) -p 49155 The authenticity of host '[192.168.59.103]:49155 ([192.168.59.103]:49155)' can't be established. RSA key fingerprint is 6c:52:de:f7:85:8f:29:69:8c:5c:78:d4:ec:43:3d:69. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.59.103]:49155' (RSA) to the list of known hosts. root@192.168.59.103's password: Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.2.0-76-generic x86_64) * Documentation: https://help.ubuntu.com/ The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@5d215294c5cf:~#
入れたー
おまけ
boot2docker
で試した理由は、docker
周辺の仕組みを理解したかったからであって、boot2docker
でないといけない理由はありません。
後、観測範囲では、何故か boot2docker
で試した例が見当たらなかったから。
ActiveSupport::Configurable の話
イントロ
よく設定ファイルで見るクラスを簡単に作れる module ActiveSupport::Configurable
の紹介
使い方は、rails/configurable.rb at master · rails/rails のコメント文を読んだほうが早い。
よくあるやつ
具体例を幾つか紹介。
引数が違ったり、ブロック引数有り/無しだったり、メソッド名が違う等の差はあれど、どれも似ている
vagrant
Vagrantfile を拝借
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "centos7" config.vm.network "private_network", ip: "192.168.33.10" .... end
rails
config/environments/development.rb
を拝借
Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false ... end
tapp
esminc/tapp より
Tapp.configure do |config| config.default_printer = :awesome_print config.report_caller = true end
rails_config
RailsConfig.setup do |config| config.const_name = 'AppSettings' config.use_env = true end
他にもあったけど、紙面の関係上省略。
使ってみる
インスタンスを使う
require 'active_support/configurable' class MyConfig include ActiveSupport::Configurable config_accessor :id, :name end c = MyConfig.new c.id = 'aaa' c.id #=> 'aaa' c.name = 'bbb' c.name #=> 'bbb' c.hoge #=> NoMethodError: undefined method `hoge'
config_accessor
でメソッド名を渡すと、(内部でゴニョゴニョしてるが)アクセサが作られるというだけ。
また、config
というインスタンスメソッドが定義されて、それを呼ぶと登録した設定が全て取れる。
c.config
#=> {:id=>"aaa", :name=>"bbb"}
クラスを使う
ActiveSupport::Configurable
を include したクラスでは、ブロックを渡すお馴染みのインターフェイスが提供される。
class MyConfig include ActiveSupport::Configurable config_accessor :id, :name end # みたことあるやつや! MyConfig.configure do |config| config.id = 'aaa' config.name = 'bbb' end MyConfig.id #=> 'aaa' MyConfig.name #=> "bbb" MyConfig.config #=> {:id=>"aaa", :name=>"bbb"}
とはいえ、これだとクラス自体が設定を持っていて、何か気持ち悪い。
応用
例えば以下のようにクラスを書いてみると、しっくりくる。
class MyApp class Config include ActiveSupport::Configurable config_accessor :id, :name end def self.configure(&block) yield config end def self.config @config ||= Config.new end end MyApp.configure do |config| config.id = 'aaa' config.name = 'bbb' end MyApp.config #=> <MyApp::Config:0x007f9b7b9ab870 @_config={:id=>"aaa", :name=>"bbb"}> config = MyApp.config config.id #=> 'aaa' config.name #=> 'bbb'
- 設定を保持するクラス(
MyApp::Config
)にActiveSupport::Configurable
を include させる- 更に
config_accessor
でアクセサを宣言する
- 更に
とするだけで
MyApp.config
とすれば設定インスタンスを参照可能- MyApp を参照できれば、誰でも
config
を知ることができる
- MyApp を参照できれば、誰でも
MyApp::Config
はアクセサを定義しているだけ
みたいな事ができ、馴染みのあるコードになってきた。
けどこれだけだと、config_acessor
の代わりに attr_accessor
でいいんじゃね?ってなる。
オプションを渡す
ところがどっこい config_accessor
にはオプションを渡すことができる。
instance_reader
と instance_writer
だ。
class MyConfig include ActiveSupport::Configurable config_accessor :id config_accessor :name, instance_reader: false end c = MyConfig.new c.id = 'aaa' c.id #=> "aaa" c.name = 'bbb' c.name #=> NoMethodError: undefined method `name'
instance_reader: false
を与えると、MyConfig#name
という reader のメソッドが提供されなくなるので、NoMethodError
になる。
instance_writer: false
はというと、その逆になる。
class MyConfig include ActiveSupport::Configurable config_accessor :id config_accessor :name, instance_writer: false end c = MyConfig.new c.id = 'aaa' c.id #=> "aaa" c.name = 'bbb' #=> NoMethodError: undefined method `name=' c.name #=> nil
今度は MyConfig#name=
というメソッドだけ提供されていないので、writer を呼ぼうとすると NoMethodError
になる。
ブロックを渡す
default 値を定義することもできて、ブロックを渡せば可能。
class MyConfig include ActiveSupport::Configurable config_accessor :id config_accessor :name do 'bbb' end end c = MyConfig.new c.name #=> "bbb"
まとめ
rails/configurable.rb at master · rails/rails
デフォルト値などを考えだすまでは attr_accessor
でいいんじゃないか...? って思いました。
けど使い方次第でしょうねー