/usr/local
だなんだと言われているけど、寝ている間に終わればいいやと放置したので特に何もせず。起きたら無事に終わっていたし、今使っていて何も問題ない。
ただ、UI は前のほうがいいな。なんかちゃちく見える。
左上の信号みたいなボタン3つの主張が激しくなった。
透明感のあるメタリックな感じが良かったのに、パステルなペイント風になってがっかりだ。
/usr/local
だなんだと言われているけど、寝ている間に終わればいいやと放置したので特に何もせず。
さくらVPSにログインするとアップグレードできるよって通知が出ていたので、14.04 にアップグレードしやした。
盛大にハマった....
$ do-release-upgradeいきなり容量が足りないときた。The upgrade has aborted. The upgrade needs a total of 55.6 M free space on disk '/boot'. Please free at least an additional 12.7 M of disk space on '/boot'. Empty your trash and remove temporary packages of former installations using 'sudo apt-get clean'.
/boot
以下のファイルのうち、最新バージョン以外を削除して再度実行すればOKだった。$ mv /usr/bin/erb{,.bak} $ mv /usr/bin/gem{,.bak} $ mv /usr/bin/irb{,.bak} $ mv /usr/bin/rake{,.bak} $ mv /usr/bin/rdoc{,.bak} $ mv /usr/bin/ri{,.bak} $ mv /usr/bin/ruby{,.bak} $ mv /usr/bin/testrb{,.bak} $ ln -sfn /opt/ruby/ruby-2.1.2/bin/* /usr/binようやく Ubuntu でも 1.9.3 がデフォルトになったのか。めでたい。
$ gem install passenger言われるままにインストールする。/opt/ruby/ruby-2.1.2/bin/passenger-install-apache2-module を実行 * To install Apache 2 development headers: Please install it with apt-get install apache2-threaded-dev * To install Apache Portable Runtime (APR) development headers: Please install it with apt-get install libapr1-dev * To install Apache Portable Runtime Utility (APU) development headers: Please install it with apt-get install libaprutil1-dev
$ aptitude install apache2-threaded-dev libapr1-dev libaprutil1-devpassengerモジュールをインストール。
$ passenger-install-apache2-moduleなぜかビルド出来ない。調べてみると unixd_config は ap_unixd_config にリネームされたらしいが、決定的な情報が出てこず、ハマる。悩む。apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/passenger.load: Cannot load /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so into server: /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so: undefined symbol: unixd_config apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/passenger.load: Cannot load /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so into server: /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so: undefined symbol: unixd_config Your Apache installation might be broken
ERR_SSL_PROTOCOL_ERROR
とか言われて接続できていないんですけどー。/etc/apache2/sites-available/default-ssl.conf
から /etc/apache2/sites-enabled/000-default-ssl.conf
とかシンボリックリンクを貼ると Redmine ではなくデフォルトページだが表示されるので、Redmine 用の設定が読み込まれていないっぽい。.conf
拡張子が必要になったらしい。$ rm /etc/apache2/sites-enabled/001-redmine $ mv /etc/apache2/sites-available/redmine{,.conf} $ ln -s /etc/apache2/sites-available/redmine.conf /etc/apache2/sites-enabled/001-redmine.conf $ service apache2 restartちゃんと読み込まれたらしい。警告が出たので、対応もした。AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/sites-enabled/001-redmine.conf:1
You don't have permission to access / on this server.
とか言われる。今まではこれで動いとってん!/var/log/apache2/error.log
には AH01630: client denied by server configuration: /var/lib/rails/redmine/public
と出力されている。redmine.conf
にパーミッション設定をすればよさげ。<VirtualHost *:443> ServerName xxx.mkt-sys.jp:443 DocumentRoot /var/lib/rails/redmine/public <Directory /var/lib/rails/redmine/public/> Options FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> SSLCertificateFile /etc/apache2/cert/ssl-cert.pem SSLCertificateKeyFile /etc/apache2/cert/ssl-cert.key PassengerEnabled on </VirtualHost>しかし、これでも動かない。わけわからん。
<VirtualHost *:443> ServerName xxx.mkt-sys.jp:443 DocumentRoot /var/lib/rails/redmine/public <Directory /var/lib/rails/redmine/public/> Options FollowSymLinks AllowOverride None Require all granted </Directory> SSLCertificateFile /etc/apache2/cert/ssl-cert.pem SSLCertificateKeyFile /etc/apache2/cert/ssl-cert.key PassengerEnabled on </VirtualHost>とせんとイカンらしい。これでようやくRedmineが表示された。
/usr/bin
から ImageMagick 関連のシンボリックリンクを削除した後に ImageMagick と RMagick を入れ替える。
$ aptitude install imagemagick libmagick++-dev $ cd /var/lib/rails/redmine $ bundle exec gem uninstall rmagick $ bundle installこれで、"ImageMagickのconvertコマンドが利用可能 (オプション)" は解決。
$ bundle exec rails c production irb(main):001:0> require 'RMagick'liblcms.so.1 が見つからないらしい。locate しても確かにいない。LoadError: liblcms.so.1: cannot open shared object file: No such file or directory - /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/extensions/x86_64-linux/2.1.0-static/rmagick-2.13.2/RMagick2.so from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/rmagick-2.13.2/lib/RMagick.rb:11:in `<top (required)>' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from (irb):1 from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:47:in `start' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:8:in `start' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands.rb:41:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>'
$ ldd vendor/bundle/ruby/2.1.0/gems/rmagick-2.13.2/lib/RMagick2.soなんとlinux-vdso.so.1 => (0x00007fff01ffe000) libMagickCore.so.5 => /usr/local/lib/libMagickCore.so.5 (0x00007f6be578c000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6be556e000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6be5267000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6be4ea1000) liblcms.so.1 => not found libtiff.so.4 => not found libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f6be4bfd000) libjasper.so.1 => /usr/lib/x86_64-linux-gnu/libjasper.so.1 (0x00007f6be49a6000) libjpeg.so.62 => /usr/lib/x86_64-linux-gnu/libjpeg.so.62 (0x00007f6be4780000) libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f6be455a000) libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f6be4348000) libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007f6be413f000) libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007f6be3f23000) libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f6be3bee000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f6be39dd000) libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f6be3677000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6be345e000) libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f6be324e000) libltdl.so.7 => /usr/lib/x86_64-linux-gnu/libltdl.so.7 (0x00007f6be3044000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6be2e40000) /lib64/ld-linux-x86-64.so.2 (0x00007f6be607c000) libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f6be2bea000) libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f6be29e5000) libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f6be27c5000) liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f6be25a3000) libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f6be239e000) libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f6be2198000)
liblcms.so.1
だけでなく、libtiff.so.4
も見つからないらしい。おろろーん。lrwxrwxrwx 1 root root 17 Jan 16 2014 /usr/lib/x86_64-linux-gnu/liblcms2.so -> liblcms2.so.2.0.5 lrwxrwxrwx 1 root root 17 Jan 16 2014 /usr/lib/x86_64-linux-gnu/liblcms2.so.2 -> liblcms2.so.2.0.5 -rw-r--r-- 1 root root 346928 Jan 16 2014 /usr/lib/x86_64-linux-gnu/liblcms2.so.2.0.5 # 省略 lrwxrwxrwx 1 root root 16 May 6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so -> libtiff.so.5.2.0 lrwxrwxrwx 1 root root 16 May 6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so.5 -> libtiff.so.5.2.0 -rw-r--r-- 1 root root 467208 May 6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so.5.2.0ライブラリのファイルもあるので、多少バージョンが違うかもしれないが強引にこれらにリンクさせてみる。
$ cd /usr/lib/x86_64-linux-gnu/ $ ln -s liblcms2.so liblcms.so.1 $ ln -s libtiff.so.5 libtiff.so.4Redmine を再起動して確認してみると、"ImageMagickのconvertコマンドが利用可能 (オプション)" もOKマークに変わっている。
$ aptitude install fonts-ipaexfont $ vim /var/lib/rails/redmine/config/configration.yml #=> rmagick_font_path に /usr/share/fonts/truetype/fonts-japanese-gothic.ttf を指定するとすんなり PNG でも日本語が表示された。
ActiveRecord::Base#attribute_names
で取得できるけど、has_many
などで定義された属性名は取得できない。ActiveRecord::Base#reflections
経由で取得できる。
user = User.first | |
# association で定義された属性の名前を取得 | |
user.reflections.keys | |
# belongs_to で定義された属性の名前を取得 | |
user.reflections.select { |_, ref| ref.macro == :belongs_to }.keys | |
# through 経由で定義された属性の名前を取得 | |
user.reflections.select { |_, ref| ref.is_a?(ActiveRecord::Reflection::ThroughReflection) }.keys |
ActiveRecord::Base#attribute_names
は文字列の配列を返すけど、こっちはシンボルの配列を返す。
まあ、普通に考えたら 2 かな?というわけで、空コミットするお仕事に戻ります。
rake routes FILL_NAME=yes
と呼び出すと、従来は
blog_posts GET /blogs/:blog_id/posts(.:format) posts#index POST /blogs/:blog_id/posts(.:format) posts#create new_blog_post GET /blogs/:blog_id/posts/new(.:format) posts#new edit_blog_post GET /blogs/:blog_id/posts/:id/edit(.:format) posts#edit blog_post GET /blogs/:blog_id/posts/:id(.:format) posts#show PUT /blogs/:blog_id/posts/:id(.:format) posts#update DELETE /blogs/:blog_id/posts/:id(.:format) posts#destroy blogs GET /blogs(.:format) blogs#index POST /blogs(.:format) blogs#create new_blog GET /blogs/new(.:format) blogs#new edit_blog GET /blogs/:id/edit(.:format) blogs#edit blog GET /blogs/:id(.:format) blogs#show PUT /blogs/:id(.:format) blogs#update DELETE /blogs/:id(.:format) blogs#destroyこうだった
rake routes
の結果が、
blog_posts GET /blogs/:blog_id/posts(.:format) posts#index blog_posts POST /blogs/:blog_id/posts(.:format) posts#create new_blog_post GET /blogs/:blog_id/posts/new(.:format) posts#new edit_blog_post GET /blogs/:blog_id/posts/:id/edit(.:format) posts#edit blog_post GET /blogs/:blog_id/posts/:id(.:format) posts#show blog_post PUT /blogs/:blog_id/posts/:id(.:format) posts#update blog_post DELETE /blogs/:blog_id/posts/:id(.:format) posts#destroy blogs GET /blogs(.:format) blogs#index blogs POST /blogs(.:format) blogs#create new_blog GET /blogs/new(.:format) blogs#new edit_blog GET /blogs/:id/edit(.:format) blogs#edit blog GET /blogs/:id(.:format) blogs#show blog PUT /blogs/:id(.:format) blogs#update blog DELETE /blogs/:id(.:format) blogs#destroyこうなります。
% rake routes | peco | awk '{print $1}' | pbcopyとかできたら便利じゃないですかね?
rake routes
だと名前があったりなかったりで欲しいものが取れないので、こんな gem を作りました。rake routes
はもっさりなので
% rake routes FILL_NAME=yes > .routesってあらかじめしておいて、
% cat .routes | peco | awk '{print $1}' | pbcopyってところですかね。
proutes
として .zshrc に登録しました。% cat .routes | peco | awk '{print $1}' | tr -d '\n' | pbcopy
rake routes
にないの?って思ってコード読んでたら、こんなの発見した。
rake routes CONTROLLER=books とすれば books_controller に関する routes だけが取れる。知らなかった。パイプ使って grep してた #rails
— pinzolo (@pinzolo) 2014, 8月 13
いや〜知らんかった。
require 'zip' | |
class ZipForWin | |
def zip_files(directory) | |
Zip::File.open("#{directory}.zip", Zip::File::CREATE) do |zipfile| | |
# 再帰的にサブディレクトリも格納する | |
Dir[File.join(directory, '**', '**')].each do |entry| | |
# 相対パスで格納 | |
entry_path = entry.sub(directory, '') | |
# windows で解凍できるように Shift_JIS へ変換 | |
sjis_entry_path = entry_path.encode(Encoding::CP932, invalid: :replace, undef: :replace) | |
zipfile.add(sjis_entry_path, entry) | |
end | |
end | |
end | |
end |
locales/ja.yml
には ActiveModel の設定は入っていないので、プラグインの locales/ja.yml
に書くことになる。locales/ja.yml
から ActiveRecord 用の設定をコピーしてくることになりがち。
ja: | |
activemodel: | |
errors: | |
messages: | |
inclusion: "は一覧にありません。" | |
exclusion: "は予約されています。" | |
invalid: "は不正な値です。" | |
confirmation: "が一致しません。" | |
accepted: "を受諾してください。" | |
empty: "を入力してください。" | |
blank: "を入力してください。" | |
too_long: "は%{count}文字以内で入力してください。" | |
too_short: "は%{count}文字以上で入力してください。" | |
wrong_length: "は%{count}文字で入力してください。" | |
taken: "はすでに存在します。" | |
not_a_number: "は数値で入力してください。" | |
not_a_date: "は日付を入力してください。" | |
greater_than: "は%{count}より大きい値にしてください。" | |
greater_than_or_equal_to: "は%{count}以上の値にしてください。" | |
equal_to: "は%{count}にしてください。" | |
less_than: "は%{count}より小さい値にしてください。" | |
less_than_or_equal_to: "は%{count}以下の値にしてください。" | |
odd: "は奇数にしてください。" | |
even: "は偶数にしてください。" |
module MyPlugin::Model | |
extend ActiveSupport::Concern | |
included do | |
__send__(:include, ActiveModel::Conversion) | |
__send__(:include, ActiveModel::Validations) | |
extend ActiveModel::Naming | |
extend ActiveModel::Translation | |
class << self | |
alias_method_chain :i18n_scope, :my_plugin_model | |
end | |
end | |
module ClassMethods | |
def i18n_scope_with_my_plugin_model | |
:my_plugin_model | |
end | |
end | |
def persisted? | |
false | |
end | |
end |
ja: | |
my_plugin_model: | |
errors: | |
messages: | |
inclusion: "は一覧にありません。" | |
exclusion: "は予約されています。" | |
invalid: "は不正な値です。" | |
confirmation: "が一致しません。" | |
accepted: "を受諾してください。" | |
empty: "を入力してください。" | |
blank: "を入力してください。" | |
too_long: "は%{count}文字以内で入力してください。" | |
too_short: "は%{count}文字以上で入力してください。" | |
wrong_length: "は%{count}文字で入力してください。" | |
taken: "はすでに存在します。" | |
not_a_number: "は数値で入力してください。" | |
not_a_date: "は日付を入力してください。" | |
greater_than: "は%{count}より大きい値にしてください。" | |
greater_than_or_equal_to: "は%{count}以上の値にしてください。" | |
equal_to: "は%{count}にしてください。" | |
less_than: "は%{count}より小さい値にしてください。" | |
less_than_or_equal_to: "は%{count}以下の値にしてください。" | |
odd: "は奇数にしてください。" | |
even: "は偶数にしてください。" |
ActiveModel::Model
を使うだろうから、サンプルコードはずいぶん変わると思います。activemodel.errors.messages.xxx
な i18n のキーを my_model.errors.messages.xxx
とかにしたかった。i18n_scope
をオーバーライドしてやるんだけど、全モデルクラスに書くのは嫌なので、インクルードするだけの共通モジュールを書くことに。
module MyModel | |
extend ActiveSupport::Concern | |
included do | |
__send__(:include, ActiveModel::Conversion) | |
__send__(:include, ActiveModel::Validations) | |
extend ActiveModel::Naming | |
extend ActiveModel::Translation | |
end | |
module ClassMethods | |
def i18n_scope | |
:my_model | |
end | |
end | |
def persisted? | |
false | |
end | |
end |
ActiveSupport::Concern
は ClassMethods
モジュールを反映させてから included
のブロックを実行するので、再度デフォルトで上書きしてしまう。
alias_method_chain
を使うなどして extend ActiveModel::Translation
の後にオーバーライドしてやればいい。
module MyModel | |
extend ActiveSupport::Concern | |
included do | |
__send__(:include, ActiveModel::Conversion) | |
__send__(:include, ActiveModel::Validations) | |
extend ActiveModel::Naming | |
extend ActiveModel::Translation | |
class << self | |
alias_method_chain :i18n_scope, :my_model | |
end | |
end | |
module ClassMethods | |
def i18n_scope_with_my_model | |
:my_model | |
end | |
end | |
def persisted? | |
false | |
end | |
end |
has_one
のサンプルとして、備考のモデルで作ってみた。# xxx_create_notes.rb | |
class CreateNotes< ActiveRecord::Migration | |
def change | |
create_table :notes do |t| | |
t.references :notable, polymorphic: true, null: false | |
t.text :note | |
end | |
add_index :notes, [:notable_type, :notable_id], unique: true | |
end | |
end | |
# note.rb | |
class Note < ActiveRecord::Base | |
belongs_to :notable, polymorphic: true | |
end | |
# notable.rb | |
module Notable | |
extend ActiveSupport::Concern | |
included do | |
after_save :save_note | |
has_one :note_store, as: :notable | |
end | |
def note | |
note_store.try(:note) | |
end | |
def note=(note) | |
build_note_store unless note_store | |
note_store.note = note | |
end | |
private | |
def save_note | |
note_store.try(:save) | |
end | |
end |
note
属性で値を直接やりとりしたかったのでこんな風に。# xxx_create_tags.rb | |
class CreateTags < ActiveRecord::Migration | |
def change | |
create_table :tags do |t| | |
t.string :name, null: false | |
end | |
add_index :tags, :name, unique: true | |
end | |
end | |
# xxx_create_taggings.rb | |
class CreateTaggings < ActiveRecord::Migration | |
def change | |
create_table :taggings do |t| | |
t.references :taggable, polymorphic: true, null: false | |
t.integer :tag_id, null: false | |
end | |
add_index :taggings, :tag_id | |
add_index :taggings, [:taggable_type, :taggable_id, :tag_id], unique: true, name: 'taggings_uk' | |
end | |
end | |
# tag.rb | |
class Tag < ActiveRecord::Base | |
unloadable | |
has_many :taggings, dependent: :destroy | |
end | |
# tagging.rb | |
class Tagging < ActiveRecord::Base | |
unloadable | |
belongs_to :tag | |
belongs_to :taggable, polymorphic: true | |
end | |
# taggable.rb | |
module Taggable | |
extend ActiveSupport::Concern | |
included do | |
has_many :taggings, as: :taggable | |
has_many :tags, through: :taggings | |
end | |
def add_tag(name) | |
return if tags.where(name: name).exists? | |
tag = Tag.where(name: name).first || Tag.new(name: name) | |
tags << tag | |
end | |
def remove_tag(name) | |
tag = Tag.where(name: name).first | |
tags.delete(tag) if tag && tags.include?(tag) | |
end | |
end | |
xxx_type
と xxx_id
は Rails に任せる。自分では処理しない。t.references :taggable, polymorphic: true
とするサンプルが多いけど、null が入ることは設計上ありえないんだから null: false
を付けておいたほうがいいと思う。save_note
では保存のみ実行しているけど、note_store.note
が nil の場合はデータサイズ的なことを考えると note_store.destroy
としてもいいと思う。(集約されるテーブルなので)
まあサンプルなのでシンプルにした。
load_path
での優先度が高く、tail -f pinzo.log: Redmineのプラグインで既存の文言を上書きする みたいなことをしないと、文言を上書きできませんでした。load_path
に登録されるため、特に何もせずに上書きされるようになっています。I18n.load_path
でなく Rails.application.config.i18n.load_path
に追加すると。なるほど
% vagrant box add centos65 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box % vagrant init centos65これで Vagrantfile が作成されたので少し編集。
# -*- mode: ruby -*- | |
# vi: set ft=ruby : | |
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | |
VAGRANTFILE_API_VERSION = "2" | |
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | |
config.vm.box = "centos65" | |
# HOSTから接続するため有効化 | |
config.vm.network "private_network", ip: "192.168.33.10" | |
# メモリを1Gにup | |
config.vm.provider "virtualbox" do |vb| | |
vb.customize ["modifyvm", :id, "--memory", "1024"] | |
end | |
end |
% vagrant up % vagrant ssh $ sudo yum check-update $ sudo yum update
$ sudo yum install wget # 公式サイトでは 32bit が Recommended されているが、こっちでないと動かない $ wget https://bitnami.com/redirect/to/38030/bitnami-redmine-2.5.2-0-linux-x64-installer.run $ chmod 775 bitnami-redmine-2.5.2-0-linux-x64-installer.run $ sudo ./bitnami-redmine-2.5.2-0-linux-x64-installer.runウィザード形式でインストールが完了するが、最初に英語を選ばないと、表示が怪しい
$ sudo cp /opt/redmine-2.5.2-0/ctlscript.sh /etc/init.d/bitnami-redmine $ sudo vi /etc/init.d/bitnami-redmineこちらを参考に少しスクリプトを編集$ chkconfig --add bitnami-redmine # ついでに起動しておく $ sudo sh /etc/init.d/bitnami-redmine
rake ci
する分には 10〜20分足らずで終わります。ちゅうか…勉強会重なりすぎやろ! うーん、もったいない! #ksgstudy #kanjava #rxtstudy
— ミウラ カズヒト(今後30年の前借り) (@kazuhito_m) 2014, 7月 12
ほんまこれ
# reattach-to-user-namespace をインストール % brew install reattach-to-user-namespace # .tmux.conf に設定追加 % echo 'set-option -g default-command "reattach-to-user-namespace -l zsh"' >> ~/.tmux.conf # Brewfile にも忘れずに追加 % echo 'install reattach-to-user-namespace' >> ~/src/github.com/pinzolo/env/Brewfileこれで tmux からの vim や gvim でクリップボードが使えるし、pbcopy も正常に動きます。
app/views/admin/plugins.html.erb
を修正してみる。
// 修正前 dataType: "jsonp", url: "http://www.redmine.org/plugins/check_updates", data: <%= raw_json plugin_data_for_updates(@plugins) %>,
// 修正後 dataType: "jsonp", url: "//www.redmine.org/plugins/check_updates", data: <%= raw_json plugin_data_for_updates(@plugins) %>,そうすると今度は別のエラーが発生する。
#!/bin/sh | |
# This script is deployed as /var/lib/rails/update_redmine.sh | |
if [ $# -eq 0 ]; then | |
echo Enter Redmine version. | |
exit 1 | |
fi | |
REDMINE_VERSION=$1 | |
export RAILS_ENV=production | |
echo "### Start update Redmine to ${REDMINE_VERSION}" | |
echo "### Download archive" | |
wget http://www.redmine.org/releases/redmine-${REDMINE_VERSION}.tar.gz | |
echo "### Extract downloaded file" | |
tar xf redmine-${REDMINE_VERSION}.tar.gz | |
echo "### Copy config files" | |
cp redmine/config/database.yml redmine-${REDMINE_VERSION}/config/ | |
cp redmine/config/configuration.yml redmine-${REDMINE_VERSION}/config/ | |
echo "### Copy installed plugins" | |
cp -r redmine/plugins/* redmine-${REDMINE_VERSION}/plugins/ | |
echo "### Execute bundle install" | |
cd redmine-${REDMINE_VERSION} | |
bundle install --path vendor/bundle --without development test | |
echo "### Setup Redmine" | |
bundle exec rake generate_secret_token | |
bundle exec rake db:migrate | |
bundle exec rake tmp:cache:clear | |
bundle exec rake tmp:sessions:clear | |
mkdir public/plugin_assets | |
echo "### Change owner" | |
cd ../ | |
chown -R www-data:www-data redmine-${REDMINE_VERSION} | |
echo "### Override current version" | |
ln -sfn /var/lib/rails/redmine-${REDMINE_VERSION} /var/lib/rails/redmine | |
echo "### Restart" | |
touch redmine/tmp/restart.txt | |
echo "### Remove downloaded file" | |
rm redmine-${REDMINE_VERSION}.tar.gz | |
echo "### Finish update Redmine" |
!
つきのものとそうでないものがあって、一般的には例外を発生させるかどうかの違いという認識だと思う。!
が付いているからといって例外を発生させるメソッドとは限らない。!
がつくと同時に保存も実行するというパターンも存在する。
@user = User.new | |
# ========== 例外発生系 ========== | |
# 保存する | |
@user.save | |
# 保存に失敗したら例外を発生させる | |
@user.save! | |
# 更新する | |
@user.update(params) | |
# 更新に失敗したら例外を発生させる | |
@user.update!(params) | |
# 新規作成する | |
User.create(params) | |
# 新規作成に失敗したら例外を発生させる | |
User.create!(params) | |
# ========== 保存実行系 ========== | |
# 指定の属性値を1増加させる | |
@user.increment(:login_count) | |
# 指定の属性値を1増加させて、保存する | |
@user.increment!(:login_count) | |
# 指定の属性値を1減少させる | |
@user.dencrement(:login_count) | |
# 指定の属性値を1減少させて、保存する | |
@user.dencrement!(:login_count) | |
# 指定の属性値の真偽を反転させる | |
@user.toggle(:available) | |
# 指定の属性値の真偽を反転させて、保存する | |
@user.toggle!(:available) |
decrement
で減らしているけど、万が一負数になってしまった場合、例外を発生させてトランザクションを失敗させる」場合(バリデーションでやれというのは置いといて)、@user.decrement!(:count)
ではなくて @user.decrement(:count).save!
と書かなければならない。becomes
と becomes!
という STI(単一テーブル継承)用のメソッドもあるが、これはちょっと別枠ですね。becomes!
は becomes
+ type
カラムの変更となっていて、変換後に保存するときに便利なのかな。あんまり STI を使ったことないけど。
<!-- 誤 --> <script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'></script> <!-- 正 --> <script src='https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js' type='text/javascript'></script>間違っていたスクリプトはモジュールだけで実行はしてくれないっぽいな。
.tmux.conf
も少し調べたらかけた。exit
で全部終了してから、再度起動しても設定ファイルを再読み込みしてくれるわけではないらしい。killall tmux
して再度立ち上げたらちゃんと反映された。.tmux.conf
はこんな感じ。
# utf-8 set-window-option -g utf8 on set-option -g status-utf8 on # prefix: C-b -> C-t unbind C-b set-option -g prefix C-t # ignore all bells set-option -g bell-action none # highlight status line on window activity set-window-option -g monitor-activity on # use vi keybinds set-option -g mode-keys vi # reduce escape key delay set-option -sg escape-time 1 # reload ~/.tmux.conf bind r source-file ~/.tmux.conf \; display "Reloaded!" # show last window bind C-t last-window # enter copy mode unbind Escape bind Escape copy-mode # enable rbenv local set-environment -gu RBENV_VERSION # default status color set-option -g status-fg black set-option -g status-bg white # current window's status color set-window-option -g window-status-current-fg blue set-window-option -g window-status-current-bg whiteこれでカラフルな vim がコンソールでも使えるようになった。
pry(main)> $LOAD_PATH.unshift './lib' pry(main)> require 'my_gem'みたいなのを毎度やっていた。
.pryrc
Pry::DEFAULT_HOOKS.add_hook(:before_session, :gem_auto_require) do |out, target, _pry_| | |
dir = `pwd`.chomp | |
gem_name = File.basename(dir) | |
if File.exist?(File.join(dir, "#{gem_name}.gemspec")) | |
lib = File.join(dir, 'lib') | |
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
if File.exist?(File.join(lib, "#{gem_name}.rb")) | |
begin | |
require gem_name | |
rescue LoadError => e | |
puts "gem_auto_require: #{e.message}" | |
end | |
end | |
end | |
end |
my_gem.gemspec
ファイルがあれば gem だと判断し、 lib/my_gem.rb
があれば自動的に require してくれる。
source 'https://rubygems.org' | |
gem 'rails' | |
# some gems | |
group :development, :test do | |
gem 'rspec' | |
gem 'rspec-rails' | |
gem 'pry' | |
gem 'pry-rails' | |
gem 'pry-byebug' | |
# some gems | |
end | |
group :test do | |
gem 'poltergeist' | |
gem 'launchy' | |
gem 'database_cleaner' | |
# some gems | |
end |
source 'https://rubygems.org' | |
gem 'rails' | |
# some gems | |
group :development, :test do | |
gem 'rspec' | |
gem 'rspec-rails' | |
gem 'pry' | |
gem 'pry-rails' | |
if RUBY_VERSION >= '2.0.0' | |
gem 'pry-byebug' | |
else | |
gem 'pry-debugger' | |
end | |
# some gems | |
end | |
group :test do | |
gem 'poltergeist' | |
gem 'launchy' | |
gem 'database_cleaner' | |
# some gems | |
end |
binding.pry
を消し忘れて push してしまいテストが終わらなかった。bundle install
のオプションをあれこれしなければいけないのはちょっとめんどくさい。できれば bundle install
と path などの使い慣れたオプションだけで完結させたい。source 'https://rubygems.org' | |
gem 'rails' | |
# some gems | |
group :development, :test do | |
gem 'rspec' | |
gem 'rspec-rails' | |
# some gems | |
end | |
group :test do | |
gem 'poltergeist' | |
gem 'launchy' | |
gem 'database_cleaner' | |
# some gems | |
end | |
local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local') | |
instance_eval File.read(local_gemfile) if File.exists?(local_gemfile) |
group :development, :test do | |
gem 'pry' | |
gem 'pry-rails' | |
gem 'pry-byebug' | |
# some gems for debug | |
end |
bundle install
する時に余計なオプションもいらない。libruby.2.1.dylib
が存在していない。--enable-shared
オプションを付けてビルドするという情報を見つけ、Ruby2.1.2を入れなおした。
CONFIGURE_OPTS="--enable-shared --with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" rbenv install 2.1.2しかしそれでも
libruby.2.1.dylib
は作成されない。redmine:send_reminders
というRakeタスクがあるが、今のプロジェクトでは進捗率80%以上のチケットはレビュー待ちなので担当者にリマインダーとして送りたくないらしい。redmine:send_reminders
から redmine:send_reminderz
に変更するだけ(最後のsをz)/Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-support-3.0.0/lib/rspec/support/version_checker.rb:28:in `raise_too_low_error': You are using capybara 2.1.0. RSpec requires version >= 2.2.0. (RSpec::Support::LibraryVersionTooLowError) from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-support-3.0.0/lib/rspec/support/version_checker.rb:18:in `check_version!' from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-rails-3.0.1/lib/rspec/rails/vendor/capybara.rb:13:in `Redmine 本体の Gemfile で' from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require' from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency' from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' .... and more
gem "capybara", "~> 2.1.0"
なのだが、RSpec3 で Capybara を使用するには 2.2.0 以上を要求される。gem "rspec", "~> 2.14.0"
で行こうと思う。/home/travis/.rvm/rubies/ruby-2.1.2/bin/ruby -I/home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib:/home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-support-3.0.0/lib -S /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/exe/rspec spec/formup/attr_def_spec.rb spec/formup/source_spec.rb spec/formup_boolean_cast_spec.rb spec/formup_included_spec.rb spec/formup_initialize_spec.rb spec/formup_load_spec.rb spec/formup_params_for_spec.rb spec/formup_source_called_spec.rb spec/formup_validation_spec.rb -cfs /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/formatters.rb:167:in `find_formatter': Formatter 's' unknown - maybe you meant 'documentation' or 'progress'?. (ArgumentError) from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/formatters.rb:126:in `add' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration.rb:624:in `add_formatter' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `block in load_formatters_into' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `each' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `load_formatters_into' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:24:in `configure' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:96:in `setup' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:85:in `run' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:70:in `run' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:38:in `invoke' from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/exe/rspec:4:in `原因はここ。'
#!/usr/bin/env rake | |
require "bundler/gem_tasks" | |
task :default => [:spec] | |
begin | |
require 'rspec/core/rake_task' | |
RSpec::Core::RakeTask.new(:spec) do |spec| | |
spec.pattern = 'spec/**/*_spec.rb' | |
spec.rspec_opts = ['-cfs'] # ← ココ!! | |
end | |
rescue LoadError => e | |
end |
s
なんてフォーマット知らないよ」ということ。bundle exec rspec --help
しても確かにそんなものはない。ていうか、2.14の頃からすでにない。function peco-src() { local selected_dir=$(ghq list --full-path | peco --query "$LBUFFER") if [ -n "$selected_dir" ]; then BUFFER="cd ${selected_dir}" zle accept-line fi zle clear-screen } zle -N peco-src bindkey '^S' peco-srcこんなのを
.zshrc
に書いたが、Ctrl-S で起動しないし、直接 peco-src
とやってディレクトリを選択するとエラーになる。peco-src:zle:4: widgets can only be called when ZLE is active peco-src:zle:6: widgets can only be called when ZLE is activeあれこれいじったり調べていると、どうも自分の zsh の環境が少しおかしいことに気づく。
% echo $module_path明らかにおかしい。どうやら、実行しているシェルは Mac に元から入っていた zsh のようだ。/usr/lib/zsh/5.0.2/zsh% zsh --versionzsh 5.0.5 (x86_64-apple-darwin13.0.0)
chsh -s /bin/zsh
したんだろう。% sudo sh -c "echo /usr/local/bin/zsh" >> /etc/shells % chsh -s /usr/local/bin/zshしかし、下記のエラーが出た。
/Users/pinzolo/.zshenv:1: command not found: rbenv /Users/pinzolo/.zshenv:2: command not found: pyenv compinit:183: module `zsh/parameter' has no such feature: `p:dis_patchars': autoload cancelled compinit:183: module `zsh/parameter' has no such feature: `p:patchars': autoload cancelledrbenv と pyenv のエラーは
.zshenv
の先頭に export PATH="/usr/local/bin:$PATH"
を追加したら消えた。% brew uninstall zsh % brew install zsh --enable-etcdirしかし、それでも
peco-src
は動かない。/usr/local/Cellar/zsh/5.0.5/lib
に zle.so
はあるし、.zshrc
内では zle
は動いていると思われる。% cd /opt/src % wget https://www.kernel.org/pub/software/scm/git/git-2.0.0.tar.gz % tar xf git-2.0.0.tar.gz % cd git-2.0.0 % ./configure --prefix=/opt/git/git-2.0.0 --with-openssl --with-curl % make % make install % /opt/git/git-2.0.0/bin/git --versiongit version 2.0.0% ln -sfn /opt/git/git-2.0.0/bin/* /usr/bin % git --versiongit version 2.0.0
ln -sfn
でシンボリックリンクが上書きできることを初めて知ったのでメモ。
/admin/info
なので、redmine/app/views/admin/info.html.erb を見るが、それらしい箇所はない。% bundle exec rails c production irb(main):001:0> require 'RMagick'libjpeg.so.62 がないのが原因のようだ。LoadError: libjpeg.so.62: cannot open shared object file: No such file or directory - /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/extensions/x86_64-linux/2.1.0-static/rmagick-2.13.2/RMagick2.so from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rmagick-2.13.2/lib/RMagick.rb:11:in `<top (required)>' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from (irb):1 from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands/console.rb:47:in `start' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands/console.rb:8:in `start' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands.rb:41:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>'
<link href='http://pinzolo.github.io/blog/style.css' rel='stylesheet' type='text/css'/>
<!-- ヘッダに --> <link href='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css' rel='stylesheet' type='text/css'/> <!-- bodyの閉じタグ直前に --> <script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'></script>しかし、ハイライトされていないっぽい。原因不明。→2014-07-03: 有効にできた
% add-apt-repository ppa:webupd8team/java
% aptitude update
% aptitude install oracle-java7-installer
% aptitude install oracle-java8-installer
変更する。
% update-alternatives --config java
There are 3 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-8-oracle/jre/bin/java 65 auto mode
1 /usr/lib/jvm/java-6-sun/jre/bin/java 63 manual mode
2 /usr/lib/jvm/java-7-oracle/jre/bin/java 64 manual mode
3 /usr/lib/jvm/java-8-oracle/jre/bin/java 65 manual mode
ん?Java8に自動的になってる?
% java -versionなってたjava version "1.8.0_05" Java(TM) SE Runtime Environment (build 1.8.0_05-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
tail -f pinzo.log: Redmine がついに Markdown をサポートしたようだ で書いたように、Redmine が 2.5.0 から試験的に Markdown をサポートしたけど、過去の Textile で書いたもろもろが崩れてしまうので、気軽に乗り換えられない。
でも、やっぱり Markdown で書きたい。主流だし。
というわけで redmine_persist_wfmt というプラグインを作った。
これで少しは気軽に Markdown に切り替えられるですよ。
$ bundle exec rake pwfmt:persist_all FORMAT=textile RAILS_ENV=production
で既存のドキュメントを Textile として保存する。もちろん Markdown として保存することもできる。
% convert
convert: error while loading shared libraries: libjpeg.so.62: cannot open shared object file: No such file or directory
convert が失敗するのが原因のようだ。% wget http://www.imagemagick.org/download/ImageMagick-6.8.9-1.tar.gz
% tar xf ImageMagick-6.8.9-1.tar.gz
% cd ImageMagick-6.8.9-1
% ./configure --enable-lzw=yes --prefix=/opt/ImageMagick/ImageMagick-6.8.9-1
% make
% make install
% /opt/ImageMagick/ImageMagick-6.8.9-1/bin/convert --version
Version: ImageMagick 6.8.9-1 Q16 x86_64 2014-05-16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib freetype jng jpeg lcms png tiff x xml zlib
インストールが成功したので、既存と置き換える。
% mv /usr/local/bin/animate{,.bak}
% mv /usr/local/bin/compare{,.bak}
% mv /usr/local/bin/composite{,.bak}
% mv /usr/local/bin/conjure{,.bak}
% mv /usr/local/bin/convert{,.bak}
% mv /usr/local/bin/display{,.bak}
% mv /usr/local/bin/identify{,.bak}
% mv /usr/local/bin/import{,.bak}
% mv /usr/local/bin/Magick-config{,.bak}
% mv /usr/local/bin/Magick++-config{,.bak}
% mv /usr/local/bin/MagickCore-config{,.bak}
% mv /usr/local/bin/MagickWand-config{,.bak}
% mv /usr/local/bin/mogrify{,.bak}
% mv /usr/local/bin/montage{,.bak}
% mv /usr/local/bin/stream{,.bak}
% mv /usr/local/bin/Wand-config{,.bak}
% ln -s /opt/ImageMagick/ImageMagick-6.8.9-1/bin/* /usr/bin
% convert --version
Version: ImageMagick 6.8.9-1 Q16 x86_64 2014-05-16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib freetype jng jpeg lcms png tiff x xml zlib
RMagick を再インストール。bundle exec gem uninstall
でエラーは出るけどちゃんと削除はされるらしい。
% cd /var/lib/rails/redmine
% bundle exec gem uninstall rmagick
Successfully uninstalled rmagick-2.13.2
ERROR: While executing gem ... (NoMethodError)
undefined method `delete' for #
% bundle install
% touch tmp/restart.txt
その結果がこれである。
なんでや・・・
% wget https://www.kernel.org/pub/software/scm/git/git-1.9.3.tar.gz
早速エラー。https対応をしていなかった。
% echo 'ca-certificate = /etc/ssl/certs/ca-certificates.crt' >> /etc/wgetrc
% wget https://www.kernel.org/pub/software/scm/git/git-1.9.3.tar.gz
% ./configure --prefix=/opt/git/git-1.9.3 --with-openssl --with-curl
% make
/bin/sh: 1: msgfmt: not found
とエラーになった。どうやらgettextが必要らしい。
% aptitude install gettext
% make
% make install
% /opt/git/git-1.9.3/bin/git --version
git version 1.9.3
インストールが成功したので、既存と置き換える。
% aptitude remove git-core
% ln -s /opt/git/git-1.9.3/bin/* /usr/bin
% git --version
git version 1.9.3
お疲れ様でした。
# readline のバージョンを最新に % brew switch readline 6.3.5 # Ruby 2.0.0-p481 をインストール % CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.0.0-p481 % rbenv global 2.0.0-p481 && rbenv rehash % gem install pry bundler # Ruby 2.0.0-p481 をインストール % CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.1.2 % rbenv global 2.1.2 && rbenv rehash % gem install pry bundler
Ubuntu 14.04 も出たけど、とりあえずさくらの VPS を Ubuntu 10.04 から 12.04 にアップグレードした。
基本的には さくらのVPSでubuntu12.04にアップデートしたら、resolv.confの中身が空っぽになった件 | 流浪のプログラマのブログ を参考に行って、resolv.conf も同じように対応したら、名前解決も無事できた。
しかし、Redmine が動かない。
どうやら、/usr/bin/ruby 等の Ruby 関連のシンボリックリンクが Ubuntu 12.04 デフォルトの 1.8.7 に上書きされたのが原因っぽい。
tail -f pinzo.log: Rubyのアップデートがちゃんとできていなくて、Redmineをアップデートできなかった で作業した ruby2.0.0-p451 の本体は当然ながらしっかり残っていたので、再度シンボリックリンクを貼って apache を再起動したら Redmine も正常稼働した。
Book.where(category: 'comics')こんなコードを書いた場合、Rails 4.0 まではこんなログが出力されていました。
Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."category" = 'comics'
でも Rails 4.1 ではこんなログが出力されます。
Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."category" = 'comics'
WHERE の前の半角スペースが 1 つ増えてます。おもむろに最新パッチレベルとそろそろruby2.1.1を入れようと思って、
CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.0.0-p451を叩いたらエラーでインストールできなかった。
readline.c:1886:26: error: use of undeclared identifier 'Function'
rl_pre_input_hook = (Function *)readline_pre_input_hook;
^
readline.c:1886:36: error: expected expression
rl_pre_input_hook = (Function *)readline_pre_input_hook;
調べてみると、どうやら readline が 6.3 になって rbenv でインストールしようとしたらエラーになるということらしい。
参考:MacでRuby 2.x.xがインストールできないバグ (homebrew + rbenv) - Qiita
readline を以前のバージョンに戻せばインストールできるとのことなので、
pinzolo@ileach % brew info readline
readline: stable 6.3.3 (bottled)
http://tiswww.case.edu/php/chet/readline/rltop.html
This formula is keg-only.
OS X provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.
/usr/local/Cellar/readline/6.2.2 (30 files, 1.6M)
/usr/local/Cellar/readline/6.2.4 (30 files, 1.6M)
/usr/local/Cellar/readline/6.3.3 (40 files, 2.1M) *
Poured from bottle
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/readline.rb
6.2.4 が入っていることを確認して、
pinzolo@ileach % brew switch readline 6.2.4
Cleaning /usr/local/Cellar/readline/6.2.2
Cleaning /usr/local/Cellar/readline/6.2.4
Cleaning /usr/local/Cellar/readline/6.3.3
Opt link created for /usr/local/Cellar/readline/6.2.4
readline を切り替えて再度インストールしたら無事インストールできた。
Redmine.org の issue を眺めていると Feature #15520: Markdown formatting - Redmine が上に上がっていた。
この要望は定期的にあがるよなーと思って読んでいると、なんととうとうサポートしたとのこと。
2.5.0 - Redmineを見ると、確かに 2.5.0 で追加されてる。
Github, Gist, Qiita, はてなブログ, wri.pe などなど Markdown はエンジニアのメモ記法のデファクトスタンダードになっているので、これは嬉しいニュース。待ち望んでいた人も多いのでは。
# Wiki | |
## テスト | |
### リスト | |
* foo | |
* bar | |
* baz | |
* bazbaz | |
1. hoge | |
1. hogehoge | |
1. fuga | |
1. fugafuga | |
1. piyo | |
1. piyopiyo | |
1. piyopiyopiyo | |
1. piyopiyopiyo | |
### 文字装飾 | |
**bold** | |
*italic* | |
~~delete~~ | |
### 引用 | |
> blockquote-1 | |
> blockquote-2 | |
> blockquote-3 | |
### pre | |
~~~ | |
pre-1 | |
pre-2 | |
pre-3 | |
~~~ | |
### シンタックスハイライト | |
```ruby | |
def test | |
"This is test method." | |
end | |
``` | |
```java | |
public static void main(String[] args) { | |
System.out.println("This is java test"); | |
} | |
``` | |
```javascript | |
function test() { | |
console.log("This is test function"); | |
} | |
``` | |
### issue link | |
#1 | |
### 改行 | |
This | |
is | |
break | |
line. |
さくらのVPSで使用している Redmine を最新にしようと思い立った。
% cd work % wget http://www.redmine.org/releases/redmine-2.5.1.tar.gz % tar xf redmine-2.5.1.tar.gz % mv redmine-2.5.1 /etc/lib/rails % cd /etc/lib/rails/redmine-2.5.1 % cp ../redmine/config/database.yml config/ % cp ../redmine/config/configuration.yml config/ % bundle install --path vendor/bundle % bundle exec rake generate_secret_token
ここまで順調に来たが、ここでエラー。
Could not find rake-10.1.1 in any of the sourcesなぜか、bundler から bundler で今しがたインストールしたはずの gem が参照できないらしい。
思い当たることは、ruby を 2.0.0 にアップデートしたこと。
「今の Redmine をインストールした → ruby 2.0.0 をインストール → 今回」なので今までの Redmine は問題なく動いていたんだろうな
しかも ruby 2.0.0 をインストールした時、手順を間違えて ruby 1.9.3 の実行ファイルを正しく更新できていなかったようだ。
つまり、gem は ruby 1.9.3 の頃のものが動いていて bundler によるインストールは 1.9.1 以下に配置するが、実行時は ruby 2.0.0 で動いているので 2.0.0 以下を参照しようとしていたということだな。
というわけなので、rubyの最新版からちゃんとインストールし直すことにした。
% wget http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p451.tar.gz % tar xf ruby-2.0.0-p451.tar.gz % cd ruby-2.0.0-p451 % ./configure --prefix=/usr/local/ruby-2.0.0-p451 % make % make install % rm /usr/bin/erb % rm /usr/bin/gem % rm /usr/bin/irb % rm /usr/bin/rake % rm /usr/bin/rdoc % rm /usr/bin/ri % rm /usr/bin/ruby % rm /usr/bin/testrb % ln -s /usr/local/ruby-2.0.0-p451/bin/* /usr/bin/
手順をミスった ruby-2.0.0-p353 が動かないように変更
% mv /usr/local/bin/erb{,.bak} % mv /usr/local/bin/gem{,.bak} % mv /usr/local/bin/irb{,.bak} % mv /usr/local/bin/rake{,.bak} % mv /usr/local/bin/rdoc{,.bak} % mv /usr/local/bin/ri{,.bak} % mv /usr/local/bin/ruby{,.bak} % mv /usr/local/bin/testrb{,.bak}
bundler をインストール
% gem install bundler % ln -s /usr/local/ruby-2.0.0-p451/bin/bundle /usr/bin/
passenger の最新をインストールして変更
% gem install passenger % cd /usr/local/ruby-2.0.0-p451 % ./bin/passenger-install-apache2-module # /etc/apache2/mods-available/passenger.load を下記に変更 LoadModule passenger_module /usr/local/ruby-2.0.0-p451/lib/ruby/gems/2.0.0/gems/passenger-4.0.41/buildout/apache2/mod_passenger.so # /etc/apache2/mods-available/passenger.conf を下記に変更 PassengerRoot /usr/local/ruby-2.0.0-p451/lib/ruby/gems/2.0.0/gems/passenger-4.0.41 PassengerDefaultRuby /usr/bin/ruby
redmine-2.5.1 のインストールのやり直し
# 同じなので省略 % bundle install --path vendor/bundle % bundle exec rake generate_secret_token % bundle exec rake db:migrate RAILS_ENV=production % bundle exec rake tmp:cache:clear RAILS_ENV=production % bundle exec rake tmp:sessions:clear RAILS_ENV=production % mkdir public/plugin_assets % cd ../ % chown -R www-data:www-data redmine-2.5.1 % ln -s /var/lib/rails/redmine-2.5.1 /var/lib/rails/redmine % service apache2 restartちゃんと表示されて一安心
先日書いた pinzolo/tekido を開発していた時、どうも一部時間のかかる処理があった。
割合系の spec を確認するために、誤差1%で合格する spec を書いていたんだけど、各sampleで試行回数10000回だとどうしても、ちょくちょく誤差を超えてしまう。
試行回数を10倍の100000回で行うと安定して、誤差内でおさまるんだけどテストの実行に結構な時間がかかっていた。
調べてみると、どうやら日付の Range
に対しての include
マッチャが時間がかかっている。
実際はマッチャは関係なく、include?
メソッドの実行が結構重い。
ドキュメントによると、cover?
だと、両端の <=> 比較によるチェックを行うということなので置き換えてみるとずいぶんと高速になったので解決はした。
そんなこともあって、せっかくなのでいろんな Range
に対して include?
, member?
, ===
, cover?
のパフォーマンスを測ってみた。
MacBook Air 13-inch, Mid 2012
プロセッサ : 2GHz Intel Core i7
メモリ : 8GB 1600 MHz DDR3
ソフトウェア : OS X 10.9.1 (Mavericks)
Ruby : ruby 2.0.0p353
# coding: utf-8 | |
require 'benchmark' | |
range = 1..5000 | |
try_count = 10000 | |
Benchmark.bm(8) do |bm| | |
bm.report('include?') do | |
try_count.times do | |
range.include?(rand(10000)) | |
end | |
end | |
bm.report('member?') do | |
try_count.times do | |
range.member?(rand(10000)) | |
end | |
end | |
bm.report('===') do | |
try_count.times do | |
range === rand(10000) | |
end | |
end | |
bm.report('cover?') do | |
try_count.times do | |
range.cover?(rand(10000)) | |
end | |
end | |
end | |
# user system total real | |
# include? 0.010000 0.000000 0.010000 ( 0.006155) | |
# member? 0.010000 0.000000 0.010000 ( 0.006968) | |
# === 0.010000 0.000000 0.010000 ( 0.008144) | |
# cover? 0.000000 0.000000 0.000000 ( 0.007070) |
# coding: utf-8 | |
require 'benchmark' | |
range = 1.chr("UTF-8")..5000.chr("UTF-8") | |
try_count = 10000 | |
Benchmark.bm(8) do |bm| | |
bm.report('include?') do | |
try_count.times do | |
range.include?(rand(10000).chr("UTF-8")) | |
end | |
end | |
bm.report('member?') do | |
try_count.times do | |
range.member?(rand(10000).chr("UTF-8")) | |
end | |
end | |
bm.report('===') do | |
try_count.times do | |
range === rand(10000).chr("UTF-8") | |
end | |
end | |
bm.report('cover?') do | |
try_count.times do | |
range.cover?(rand(10000).chr("UTF-8")) | |
end | |
end | |
end | |
# user system total real | |
# include? 4.100000 0.010000 4.110000 ( 4.132348) | |
# member? 4.070000 0.010000 4.080000 ( 4.098094) | |
# === 3.930000 0.000000 3.930000 ( 3.949908) | |
# cover? 0.010000 0.000000 0.010000 ( 0.007477) |
cover?
だけど、10000回で4秒ちょい、1回あたり0.4ミリ秒なら include?
が使われててもまあ別にいいかなと思うレベル。(状況にもよるけど)
# coding: utf-8 | |
require 'date' | |
require 'benchmark' | |
begin_date = Date.today << 12 * 10 | |
end_date = Date.today | |
range = begin_date..end_date | |
try_count = 10000 | |
Benchmark.bm(8) do |bm| | |
bm.report('include?') do | |
try_count.times do | |
date = Date.today - rand(2000) | |
range.include?(date) | |
end | |
end | |
bm.report('member?') do | |
try_count.times do | |
date = Date.today - rand(2000) | |
range.member?(date) | |
end | |
end | |
bm.report('===') do | |
try_count.times do | |
date = Date.today - rand(2000) | |
range === date | |
end | |
end | |
bm.report('cover?') do | |
try_count.times do | |
date = Date.today - rand(2000) | |
range.cover?(date) | |
end | |
end | |
end | |
# user system total real | |
# include? 24.040000 0.050000 24.090000 ( 24.167171) | |
# member? 24.160000 0.050000 24.210000 ( 24.288291) | |
# === 24.150000 0.050000 24.200000 ( 24.282828) | |
# cover? 0.020000 0.000000 0.020000 ( 0.021473) |
範囲内チェックは一律 cover?
を使うのが無難そうです。
RSpec にも cover
マッチャがあるので単純に置き換えできます。
ちなみに、Windows7 32bit環境(MBAよりもスペックは低い)で試してみたら、数値と文字列は変わらなかったけど日付の上三つの処理時間は13秒ぐらいでした。
MBAよりも倍近く高速なのが興味深い。
先日お仕事で、ランダムなデモデータを作成する必要がありまして、そのとき感じたことをいくつか。
rand(0..2)
と値ぐらいならいいが、 rand(0..2).zero? ? "foo" : "bar"
みたいなコードを結構使うが、意味が汲み取りにくい。というわけで、ランダムデータ作成用に gem を作ってみた。
pinzolo/tekido
tekido | RubyGems.org
適度にデータを作るようにということで tekido。
使い方は、 Tekido.integer
とか Tekido.date
とか Tekido.string
でよく使うデータ型のランダムなデータを作成出来ます。Tekido.percent
や Tekido.email
や Tekido.birthday
みたいなちょっといい感じににしてくれるメソッドもついてます。
Kernel.rand
のように引数で色々作成するデータが変わるので詳しくは README.md や USAGE_ja.md を見てください。
rand
を多用するよりはメソッド名で意味を汲み取りやすいし、普段なら一手間かかるデータも一発で作れます。
これで、ランダムデータの作成も少しは楽になるかもしれません。
Railsでの区分値の扱いについて考える - TIM Labs
ActiveHashを使ってRailsで区分値を扱う方法 - TIM Labs
このあたりを読んでの話。
自分の場合は、もっぱらDBに保存する派です。
まあ、理由はいくつかあって
でもDBに保存した場合、二重管理というのは確かに頭を悩ませる問題ですね。
def self.male
find(id: 1)
end
みたいなコードを過去には量産してしまったりしてました。pinzolo/mastar という gem で、以下その紹介。
id | name | code |
---|---|---|
1 | 日本 | japan |
2 | アメリカ合衆国 | usa |
こんなテーブルに対して、
class Country
include Mastar
mastar.key :code
end
とすれば、Country.japan
で find(1)
の結果にアクセスできます。
code
のような、一意なコードを扱う列を作らなければいけないですが、二重管理からは開放されるので個人的には重宝してますね。
機能だけ作って README.md 書くのがめんどくさくなって v0.9.0 としてひっそりリリースして放置してました。
せっかくなので Country
クラスのオブジェクトに対して japan?
で判別できるメソッドが生える機能を足して v1.0.0 としてリリースしました。
もし使えそうなら使ってみてください。
あ、あと view でドロップダウンリストのために f.select :country_id, Country.all.map { |c| [c.name, c.id] }
やら f.collection_select :country_id, Country.all, :id, :name
と書いていたのを f.select :country_id, Country.pairs
と書けるようにもなります。地味に気に入ってます。
rails-flog(github, RubyGems.org) をバージョン 1.3.0 にあげた。
issue や pull request もお気軽にどうぞ