ラベル rubygems の投稿を表示しています。 すべての投稿を表示
ラベル rubygems の投稿を表示しています。 すべての投稿を表示

2016/01/10

EC2(Amazon Linux)上のRailsアプリにQiita::Markdownをインストール

インストール

Qiita::Markdownはシンタックスハイライトに Pygments を使用しているのでインストールしておく(sudo pip install pygments)

そして、おもむろに Gemfile に gem 'qiita-markdown' として bundle install してみる。

Installing charlock_holmes 0.7.3 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /usr/bin/ruby2.2 -r ./siteconf20160110-30152-1igbivj.rb extconf.rb
checking for main() in -licui18n... no
which: no brew in (/home/ec2-user/bin:/home/ec2-user/.rbenv/bin:/home/ec2-user/bin:/home/ec2-user/.rbenv/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/opt/aws/bin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/opt/aws/bin)
checking for main() in -licui18n... no


***************************************************************************************
*********** icu required (brew install icu4c or apt-get install libicu-dev) ***********
***************************************************************************************
*** 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
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib64
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/$(RUBY_BASE_NAME)2.2
        --with-icu-dir
        --without-icu-dir
        --with-icu-include
        --without-icu-include=${icu-dir}/include
        --with-icu-lib
        --without-icu-lib=${icu-dir}/lib64
        --with-icui18nlib
        --without-icui18nlib
        --with-icui18nlib
        --without-icui18nlib

extconf failed, exit code 1

Gem files will remain installed in /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/gems/charlock_holmes-0.7.3 for inspection.
Results logged to /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/extensions/x86_64-linux/2.2/charlock_holmes-0.7.3/gem_make.out
Installing rugged 0.24.0b11 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /usr/bin/ruby2.2 -r ./siteconf20160110-30152-1y0cp2j.rb extconf.rb
checking for gmake... yes
checking for cmake... no
ERROR: CMake is required to build Rugged.
*** 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
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib64
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/$(RUBY_BASE_NAME)2.2
        --use-system-libraries

extconf failed, exit code 1

Gem files will remain installed in /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/gems/rugged-0.24.0b11 for inspection.
Results logged to /home/ec2-user/rails_app/vendor/bundle/ruby/2.2/extensions/x86_64-linux/2.2/rugged-0.24.0b11/gem_make.out

とまあ、2つのエラーが出た。Amazon Linuxは yum だからlibicu-dev じゃなくて libicu-devel にすればOKかな?

sudo yum install -y libicu-devel cmake して bundle install したらインストールは成功したようだ

ハイライト

インストールは成功したのでこんなコードを書いて使えば Markdown に変換された。ばっちりばっちり

module ApplicationHelper
  def markdown(source)
    Qiita::Markdown::Processor.new.call(source)[:output].to_s.html_safe
  end
end

変換はばっちりだがシンタックスハイライトがされていない。いや、正確にはスタイルシートがない。
richleland/pygments-css あたりでお好みのものを利用させてもらおう

絵文字

シンタックスハイライトも完了した。次は絵文字である。
gemoji | RubyGems.org | your community gem host がインストールされているはずなので、Rakefile に下記の行を加える。

load 'tasks/emoji.rake'
あとは bundle exec rake emoji を実行すれば /public/images/emoji 以下に画像はファイルが配置される。
これだけで絵文字が表示できるようになる。bundlerake で導入できるので /public/images/emoji.gitignore に加えておいてもいいかもしれない。大量に画像ファイルをリポジトリに登録したくないもんね

2015/11/16

RubyとRailsとminitestのマルチバージョンでのCI環境の話

pinzolo/rails-flog の Rails4.2でのテストが落ちてて、でも動いてるしーで放置してしまってた。
んで、ちゃんとしないとと思って調べてみたら、テストを壊していたのはテストコード(と自分の思い込み)だった。
具体的には mocha というモックライブラリを使用していたんだけど、スタブ作ったらテストケースをまたいで存在し続けるのを、テストケースセーフだと思い込んでいた。以前のバージョンではシーケンシャルにテストが行われていたけど、ランダムになったのでテストが落ちるようになった。
どうりでローカルでテストすると時々によってエラーの数が違うわけだ。
んで、minitest にもモック・スタブ機能があることを知り、ブロックでの影響範囲を限定できるのでこっちのほうがいいじゃん!!と mocha を削除し minitest のスタブに統一した。
ここまで前置き

ローカルでテスト通ったーと喜んで push すると travis でコケる
Ruby1.9&Rails3.2ではstubなんてないよと怒られ、Ruby2.2&Rails3.2では 'minitest/autorun'がないと怒られた。 Ruby1.9に同梱されている minitest には minitest/mock がまだ存在していなかったらしい。

調べてみると明示的に最新の minitest を使うのが良いらしく、gemspec に足してみた。
するとこんどは Rails3.2で軒並みコケた
警告も出てるし、いくつか試行錯誤してRails3.2では minitest のバージョンを 4.7.x となるように指定したら、今度はRuby2.2の時だけtest-unitが足りないと言われる。
そういや削除されたんだったっけ。
これでようやく全部通った。なまじ同梱されてるから環境の差分を調整するのはしんどい。

2015/10/30

自作gemのテストを test-unit で行う

久しぶりに自作 gem でも作るかと bundle gem -t とすると自動的に spec フォルダと .rspec が作成された。
いやいや、test-unit 使いたいんだってば。
仕方ないので自分で設定することに
gemspec に spec.add_development_dependency 'test-unit' を追加し、Rakefile にこんな感じに設定を書くだけだった。

2014/08/28

更新ないけど維持はしてるよ

少し前ですがRails4.0.9と4.1.5がリリースされたので、自作の Rails 関連の gem がちゃんと動くかな?と Travis の Job を動かしてみたら、まあ無事に全部通ったんです。
travis-ci.org に行って、Restart ボタンを押すだけの簡単なお仕事。
それはいいんだけど、Ruby や Rails 界隈では更新のない gem は使わない、使用を控える、同じ機能なら新しい方、開発が活発な方という指針が一部あって(そんな気がする)、せっかく最新バージョンでも動くのにバグフィックスや機能追加がない、つまり更新がないだけで使われない gem も出てくるわけです。
さすがにあまりないだろうけど、更新がないだけで後発の同じ機能を持つ車輪の再発明 gem の方を優先されたら作者としては悔しいわけです。動くのに。
でも「travis-ci.org に行って、Restart ボタンを押すだけの簡単なお仕事」だけだと、Github にも Rubygems.org にも維持してる証拠が残らないんですよね。
gem の選別してる時に、Github で最終更新日や README.md に載ってる CI のバッジでの最終ビルド結果は見ても、そこから CI のサイトで、最新の Rails や Ruby のバージョンでビルドしてることまで見るんだろうか?
自分は毎回そこまで見ていない気がするし、そうしてくれたら嬉しいけど、そこまでを分化としていくのは難しい気がする。
となると、やはり何らかの証拠を作者が残すしかない。

1. バージョン上げる

確実だし、Github にも Rubygems.org にも証拠が残る。
自分の基本的なバージョン指針は「0.0.1 が開発中、たまに 0.5.x とか 0.9.x で Pre-release や RC を経て、最初の想定していた機能ができたら、1.0.0 としてリリースし、その後は、機能追加でマイナーバージョンをあげて、バグフィックスなどの機能を追加しない修正はリビジョン(tiny)を上げる」というものなんだけど、この場合リビジョン上げるていいのかどうか悩む。
ソースコードに変更がないのにいたずらにバージョンを上げるべきじゃないと思うし、バージョンあげてしまうと利用者全員に自分と同じような作業が発生する可能性がある。なのでバージョンは上げたくない。

2. CIを空コミットで回す

Github には証拠が残る。Rubygems.org はそのまんま。
コミットメッセージに「Railsバージョンアップによる確認のための空コミットだよ」みたいなコメントを残しておけばわかりやすい。

3. README.mdにログを残す

Github には証拠が残る。Rubygems.org はそのまんま。
基本的に Changelog は書いてるので、そこに追記するか、Change してねーだろってんなら Activity log みたいなセクションを設けて記述する。
Github まで行って README.md 読まない奴はあまりおらんだろうという想定。
ファイルの最終更新まで変更されるし自動的にコミットも伴うから、空コミットより訪問者にわかりやすい。
しかし、普通そういうログは確認後に残すものだから Travis 回して確認 → ログ書いて commit, push はめんどくさい。

まあ、普通に考えたら 2 かな?というわけで、空コミットするお仕事に戻ります。

2014/08/15

rails-froutes という gem をリリースした

Summary

Rails の routes を peco りたかったんで rails-froutes という gem を作りました。
Github: pinzolo/rails-froutes
RubyGems.org: rails-froutes

How?

インストールして、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
こうなります。

Why?

ほら routes.rb みれば大体わかるとはいえ、ちょっと規模が大きくなると **_path, とか **_url を頭の中でごにょごにょするのはタルいわけです。
% 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 に登録しました。
guard で routes.rb 監視して、更新したら吐き出すようにしておくのもいいかもしれません。
そこまで routes.rb を頻繁にいじるかどうかはわかりませんが。

2014-08-16 追記:
改行が入るのは使いづらいのでコマンドを改良した。
% cat .routes | peco | awk '{print $1}' | tr -d '\n' | pbcopy

おまけ

こんなふうに出力するオプションって rake routes にないの?って思ってコード読んでたら、こんなの発見した。 いや〜知らんかった。

2014/06/27

gem 開発が少し便利になる .pryrc

gem の動きを pry で確認するのはよくあることで、
pry(main)> $LOAD_PATH.unshift './lib'
pry(main)> require 'my_gem'
みたいなのを毎度やっていた。
誰かの gem の挙動を確認したいなーというだけならまだいいけど、自分で開発している時に何度もやるのはめんどくさい。
そんな時に役に立つのが .pryrc こんなのを書いておいた。
カレントディレクトリに my_gem.gemspec ファイルがあれば gem だと判断し、 lib/my_gem.rb があれば自動的に require してくれる。

2014/06/10

rails-render_hooks という gem を作った

Redmine のプラグインなんかを作っていると、アクションの処理が終了してレンダリングされる前にちょっと手を入れたくなる。
実際そういう需要はそれなりにあるようで、'rails before_render' とかで検索するとチョロチョロ出てくる。
しかし、Rails3.2〜Rails4.1で動くぐらいにメンテされている gem がない。
  • shell/rails3_before_render
    Rails4 で動かないし、Rails4で動くように修正されたプルリクエストも放置
  • nilesh/before_render
    上記から fork して Rails4 で動くけど、逆に Rails3.2 で動かない
  • codepodu/rails3_before_render
    上記のプルリクエスト元なのでどっちでも動くけどRails4.1だとテスト落ちる。そもそも Travisこけてるけど放置。プルリクエスト用だから gem になってない
というわけで、自分で作った ついでに、before だけでなく、after と around も足しておいた。使うかどうかは知らないけど。

2014/05/16

[未解決]UbuntuをアップグレードしたらRedmineでRMagick関連が動かなくなっていた

さくらのVPSのUbuntu10.04を12.04に上げたらいつの間にかRedmineのRMagic関連機能が使えなくなっていた。
% convert
convert: error while loading shared libraries: libjpeg.so.62: cannot open shared object file: No such file or directory
convert が失敗するのが原因のようだ。
10.04の時はリポジトリのバージョンが古くソースからインストールしたので今回も最新版をソースからインストールした。
% 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
その結果がこれである。
なんでや・・・

2014/04/12

Rubyのアップデートがちゃんとできていなくて、Redmineをアップデートできなかった

さくらの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 が参照できないらしい。
調べてみると、どうやら bundler が実行時に参照するのは vendor/bundle/ruby/2.0.0 以下、しかしインストール時にインストールしていたのは vendor/bundle/ruby/1.9.1 以下というちぐはぐな状態になっていた。

思い当たることは、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

ちゃんと表示されて一安心

2014/02/17

ランダムデータを作るときにちょっとは役に立つかもしれない gem を作った

先日お仕事で、ランダムなデモデータを作成する必要がありまして、そのとき感じたことをいくつか。

  • rand(0..2) と値ぐらいならいいが、 rand(0..2).zero? ? "foo" : "bar" みたいなコードを結構使うが、意味が汲み取りにくい。
  • 直接関係ない値はついつい固定値にしてしまいがち。おかげで、ほとんどのデータが同じメールアドレスとか誕生日とか。そして、あとで他の機能からそのデータを使うときに、またランダム生成する。
  • そもそもランダムなメールアドレスや日付などは一手間かかる。この手のデータ作成は一時的な使い捨てであることも多々あるので、ちょくちょく同じような処理を書くことになる。

というわけで、ランダムデータ作成用に gem を作ってみた。

pinzolo/tekido
tekido | RubyGems.org

適度にデータを作るようにということで tekido。
使い方は、 Tekido.integer とか Tekido.date とか Tekido.string でよく使うデータ型のランダムなデータを作成出来ます。
Tekido.percentTekido.emailTekido.birthday みたいなちょっといい感じににしてくれるメソッドもついてます。
Kernel.rand のように引数で色々作成するデータが変わるので詳しくは README.mdUSAGE_ja.md を見てください。

rand を多用するよりはメソッド名で意味を汲み取りやすいし、普段なら一手間かかるデータも一発で作れます。
これで、ランダムデータの作成も少しは楽になるかもしれません。

2014/02/09

自分流 Rails での区分値

Railsでの区分値の扱いについて考える - TIM Labs
ActiveHashを使ってRailsで区分値を扱う方法 - TIM Labs

このあたりを読んでの話。

自分の場合は、もっぱらDBに保存する派です。
まあ、理由はいくつかあって

  • SQLで使いやすい
    過去のしごとで「アプリケーションの機能を作る程ではないけどこういう統計情報がほしい」という依頼を受けることがわりとあって、その時に画面表示と同じ文言を JOIN だけで出せる。
    区分が増えるほど CASE が増えていく SQL は書くのも保守するのもしんどい。
    Rubyを通さないと区分と文言の定義を正しく取れないのは使いづらい。
  • 区分を増やしてもアプリケーションの更新が必要ない場合がある
    区分値というのはドロップダウンリスト、チェックボックスのリスト、ラジオボタンのリストなどで画面から選択させることがよくあります。
    そんな場合、マスタ管理の機能を組み込むなり、INSERT実行するなりでアプリケーションの更新なしで対応できます。
    プログラム内で区分値を特定して使用する場合に初めてアプリケーションの更新が必要というのは理にかなってると思う。
  • 区分の保存先は統一したい
    数が少ない区分はコードで定義したほうが使いやすいが、付随する情報が多い区分はDBに保存したくなりません?
    でも保存先が分散されるのは保守しづらいのでどこかに統一したい。そんな場合、大は小を兼ねるでDBを選択してます。
というメリットが大きいな、使いやすいなと感じています。

でもDBに保存した場合、二重管理というのは確かに頭を悩ませる問題ですね。

def self.male
  find(id: 1)
end
みたいなコードを過去には量産してしまったりしてました。
それはやっぱりよろしくないので、自分の場合はちょっとした gem を作って対応してます。

pinzolo/mastar という gem で、以下その紹介。

countries
id name code
1 日本 japan
2 アメリカ合衆国 usa

こんなテーブルに対して、

class Country
  include Mastar
  mastar.key :code
end

とすれば、Country.japanfind(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 と書けるようにもなります。地味に気に入ってます。

2014/01/26

Update rails-flog to v1.3.0

rails-flog(github, RubyGems.org) をバージョン 1.3.0 にあげた。

  • バージョン 1.2.0
    一時的にフォーマットを無効にする機能をパラメータとSQL個別に行えるようにした。
    どっちかのフォーマットだけ欲しい人も安心。
  • バージョン 1.3.0
    いくつかのフォーマットを行わないための条件を設定できるようにした。 「キャッシュされたクエリはフォーマットしたくない」とか「時間のかかるクエリだけ調査したいからフォーマットしてほしい」とか「キーが一つしかないパラメータをフォーマットすんなよ。行数増えて余計見づらいわ」みたいな人もニンマリ。
    ただし、デフォルトの挙動が変わっているので注意。

issue や pull request もお気軽にどうぞ

2013/12/07

Railsのログに出力されるパラメータとSQLを整形するgemを作った

最初に

この記事は Ruby on Rails Advent Calendar 2013 - Qiita [キータ] の7日目の記事です。
前日は a_suenami さんの Railsでサービスとフォームを導入してみる話 - assertInstanceOf('Engineer', $a_suenami) です。

本題

こういう gem を作りました。

pinzolo/rails-flog - Github
rails-flog - RubyGems.org

Gemfile に下記を追加して bundle install するだけで、ログに出力されるパラメータとSQLが整形して出力されるようになります。

gem 'rails-flog', :require => 'flog'

Redmine でのスクリーンショットはこんな感じ。

使用前

使用後

Railsアプリケーションに tmp/no-flog.txt を配置すれば一時的に整形をやめることもできます。

残念なところ

  • 実装が結構強引。二重の特異メソッドとかどうなんでしょうね。完全に元の実装依存だし。
  • パラメータはスペース整形だけど、SQLはタブ整形。こいつ のせい。

作った経緯

  1. 先日、西脇.rb & 東灘.rb 合同もくもく会 7th - 西脇.rb & 東灘.rb に参加した時に、@jnchito さんが、色々と awesome_print で出力するWebサービスを作成されてて、その際にログに出力される複雑なパラメータを手作業で整形するのがタルいみたいな事をおっしゃってまして、「あるある」と思っていた。
  2. んで、複雑なSQLもタルいよなー、整形してログに出力させるぐらいならできんじゃね?
  3. anbt-sql-formatter てのがあるじゃない。イケそう。
  4. 誰か作ってんじゃない?と調べてみると Railsのログに出力されるパラメータやSQLを整形する - ( ꒪⌓꒪) ゆるよろ日記 というそのものなものが見つかる。しかも自分でブクマ済み。
  5. もう少し調べてみるとどうやら同等の機能をもつ gem は存在していないみたい。
  6. 作ってみるか。

思うところ

我々エンジニアは誰しも素晴らしいプロダクトやサービスを作りたいと思っていると思います。
そして多くの人が時間、技術力、アイデア、ビジョン等々の不足であきらめているのでしょう。
でもエンジニアの本質は「素晴らしい物を生み出す」よりも、「一歩進める」ことだと思っています。
ひとが考えもしない方向へ一歩進められたり、一歩がとっても大きい人が素晴らしいプロダクトやサービスを生み出せるのでしょう。
出来なかったことをできるようにしたり、自動化したり、簡略化したり、みんな一歩進めた結果です。
rails-flogも、アイデアも実装手段も他の巨人に乗っかったものですが、gemにするという一歩だけ進めることが出来ました。
一歩進めるだけなら誰にでもできるでしょう、さああなたも身近なものを一歩進めてみてください。

Next

明日は znz さんです。

2013/11/06

OS X Mavericks にすると gcc-4.2 がなくなるらしい

bundle installしたらエラーになった。

pinzolo@ileach [master] % bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/......... Fetching gem metadata>from https://rubygems.org/.. Resolving dependencies... Using rake (10.1.0) Using i18n (0.6.5) Using minitest (4.7.5) Using multi_json (1.8.2) Installing atomic (1.1.14) Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension. /Users/pinzolo/.rbenv/versions/2.0.0-p195/bin/ruby extconf.rb *** 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 --without-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=/Users/pinzolo/.rbenv/versions/2.0.0-p195/bin/ruby --with-atomic_reference-dir --without-atomic_reference-dir --with-atomic_reference-include --without-atomic_reference-include=${atomic_reference-dir}/include --with-atomic_reference-lib --without-atomic_reference-lib=${atomic_reference-dir}/ /Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:431:in `try_do': The compiler failed to generate an executable file. (RuntimeError) You have to install development tools first. from /Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:516:in `try_link0' from /Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:814:in `try_run' from extconf.rb:26:in `
' Gem files will remain installed in /Users/pinzolo/projects/detox/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14 for inspection. Results logged to /Users/pinzolo/projects/detox/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14/ext/gem_make.out An error occurred while installing atomic (1.1.14), and Bundler cannot continue. Make sure that `gem install atomic -v '1.1.14'` succeeds before bundling.

mkmf.log見ろって言われたので見てみる。

pinzolo@ileach [master] % cat vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14/ext/mkmf.log
"gcc-4.2 -o conftest -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0/x86_64-darwin12.4.0 -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0/ruby/backward -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0 -I. -I'/Users/pinzolo/.rbenv/versions/2.0.0-p195/include' -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -Wno-error=shorten-64-to-32 -fno-common -pipe conftest.c -L. -L/Users/pinzolo/.rbenv/versions/2.0.0-p195/lib -L. -L'/Users/pinzolo/.rbenv/versions/2.0.0-p195/lib' -lruby.2.0.0 -lpthread -ldl -lobjc " sh: gcc-4.2: command not found checked program was: /* begin */ 1: #include "ruby.h" 2: 3: int main(int argc, char **argv) 4: { 5: return 0; 6: } /* end */
gcc-4.2がないらしい。

どうやら Mavericks にしたら、gcc-4.2gccになるらしい。

sudo ln -s /usr/bin/gcc /usr/bin/gcc-4.2したら、解決した。

2012/10/12

RSpec で undefined method `fixtures'

RSpec で fixtures が動かない

rspec でテストデータを用意して、fixtures メソッドを使用したら、そんなメソッドねーよ。と言われた。

/Users/pinzolo/projects/mastar/spec/mastar/name_value_pair_spec.rb:30:in `block (2 levels) in <top (required)>': undefined method `fixtures' for #<Class:0x007faa888623a8> (NoMethodError)
    from /Users/pinzolo/projects/mastar/vendor/bundle/ruby/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `module_eval'
    from /Users/pinzolo/projects/mastar/vendor/bundle/ruby/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `subclass'
...

TestFixtures を include してみる

spec_helper.rb に下記を追加してみる。

require 'rspec'
RSpec.configure do |config|
    config.include ActiveRecord::TestFixtures
end

実行してみる。

/Users/pinzolo/projects/mastar/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.8/lib/active_record/fixtures.rb:728:in `block in <module:TestFixtures>': undefined method `setup' for #<Class:0x007fb3c20527d8> (NoMethodError)
    from /Users/pinzolo/projects/mastar/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/concern.rb:119:in `class_eval'
    from /Users/pinzolo/projects/mastar/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/concern.rb:119:in `append_features'
...

こんどは setup がないと。

調べてみると

https://github.com/rspec/rspec-rails/blob/master/lib/rspec/rails/fixture_support.rbを見ると RSpec::Rails::FixtureSupport を include していて、その時に各種設定メソッドが追加されている。

結局

rspec-rails をインストールしないと fixtures は使えないのか。
できれば、関連 gem を増やしたくないので、他の手段を考えよう。
factory-girl がいいのかな。

2012/05/14

rbenv で rubygem をインストールしても command not found となる場合

rails の開発環境をぼちぼちと整えようと思って、とりあえずグローバルな gem として pry と bundler だけインストールした。
ところが、pry はターミナルから使用できるが、bundle コマンドは command not found となった。
rbenv をインストールしていると、$HOME/.rbenv/shims と $HOME/.rbenv/bin に PATH が通っているはずなので、$HOME/.rbenv/shims を覗いてみた。
$ ll $HOME/.rbenv/shims
drwxrwxr-x 2 pinzolo pinzolo 4096  5月 14 07:52 .
drwxr-xr-x 9 pinzolo pinzolo 4096  5月 11 11:46 ..
-rwxrwxr-x 2 pinzolo pinzolo  100  5月 14 07:18 coderay
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 erb
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 gem
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 irb
-rwxrwxr-x 2 pinzolo pinzolo  100  5月 14 07:18 pry
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 rake
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 rdoc
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 ri
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 ruby
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 testrb
こんな風になってた。全て同じサイズ??ということで diff を取ってみると、ファイル名以外は全て同じらしい。
$ cat shims/pry
#!/usr/bin/env bash
set -e
export RBENV_ROOT="/home/pinzolo/.rbenv"
exec rbenv exec "${0##*/}" "$@"
環境変数を設定して、rbenv 経由で処理を実行しているのね。
というわけで、bundle という名前でファイルをコピーしてやれば良さそうだ。
$ cp $HOME/.rbenv/shims/{pry,bundle}
$ bundle
Could not locate Gemfile
# 2012-05-15 追記
単に rehash していなかっただけだった
rbenv rehash しても command not found になるなら、お試し下さい。