Posted on November 8th, 2009 by masayuki | | Filed in tips
rails's arel at master - GitHub
Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex of SQL queries and it 2) adapts to various RDBMS systems. It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database compatibility and query generation.
「Relational Algebra」を辞書でひくと「関係代数(の演算子)」と出てきますが、arelはRDBMSのクエリを簡単に記述する為のライブラリです。使い方のイメージとしては、LINQ to SQLが一番近いと思います。ドキュメントには、
The long term goal, following both LINQ and DataMapper, is to have Arel adapt to engines beyond RDBMS, including XML, IMAP, YAML, etc.
と書かれてます。
arelを動かそうと思ったのですが、0.1.0はgemで入るもののうまく動かなかったので、0.1.3で試しました。0.1.3はactivesupport(3.0.pre)に依存してる為、Dr Nic ’s First look at rails 3.0.preを見て3.0.pre環境を作成しています。
script/consoleで動かしてみました。
1
2
3
4
5
6
7
|
>> require 'arel'
=> []
>> tickets = Table(:tickets)
=> #<Arel::Table:0xb796f5c0 @engine=#<Arel::Sql::Engine:0xb7803e84 @ar=ActiveRecord::Base>, @name="tickets">
>> tickets.where(tickets[:name].matches("test%")).each do |t|
>? puts t[tickets[:name]]
>> end |
上記のように、SQLを気にすることなくオブジェクトの集合に対して処理を行うことができます。
ただ、値の取得に関する記述(t[tickets[:name]])や、下記に示すようにレコードの関連を使おうとすると、その記述はまだ冗長なカンジがします。
1
2
3
4
|
>> tickets.join(categories).on(tickets[:category_id].eq(categories[:id])).where(categories[:name].matches("%2"))\
.each do |t|
?> puts t[tickets[:name]]
>> end |
LINQ to SQLは仕事で使っていたのですがとても便利でした。arelも同じくらい使い勝手が良くなるポテンシャルがあると思います。
Posted on August 8th, 2009 by masayuki | Filed in tips
adduserで--systemと指定すると、systemユーザを作ることができる。systemユーザっていうスキームがあるんですね。付与されるUIDの範囲以外に何か違うんだろうか。
adduser will choose the first available UID from the range specified
for system users in the configuration file (FIRST_SYSTEM_UID and
LAST_SYSTEM_UID). If you want to have a specific UID, you can specify
it using the --uid option.
By default, system users are placed in the nogroup group. To place the
new system user in an already existing group, use the --gid or
--ingroup options. To place the new system user in a new group with
the same ID, use the --group option.
A home directory is created by the same rules as for normal users. The
new system user will have the shell /bin/false (unless overridden with
the --shell option), and have logins disabled. Skeletal configuration
files are not copied.
併せて、--no-create-homeを指定するとhomeディレクトリを作らない。--systemと併せて--groupを指定すると同じ名前でグループを作成してくれるので、バックグラウンドで動かすプロセスの実行ユーザを作成する場合、
|
adduser --system --group --no-create-home ユーザ名(グループ名) |
で良いと。
Posted on July 25th, 2009 by masayuki | Filed in tips
クラスやモジュールが定義されるタイミングを知りたくてコードを追っていたところ、Rails2.3.2のCHANGELOGに以下のような記述があることに気がつきました。
* Add debugging logging to Dependencies. Currently can be enabled with Dependencies.log_activity = true; adding to Initializer and documenting is forthcoming. [Nicholas Seckar]
RAILS_ROOT/config/environment.rbで以下のように設定すると、
1
2
|
ActiveSupport::Dependencies.logger = Logger.new(STDOUT)
ActiveSupport::Dependencies.log_activity = true |
以下のように、ロードまわりがロギングされます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Processing HogesController#index (for ::ffff:192.168.181.1 at 2009-07-25 20:24:45) [GET]
Hoge Load (1.5ms) SELECT * FROM "hoges"
Rendering template within layouts/hoges
Rendering hoges/index
Completed in 22ms (View: 11, DB: 2) | 200 OK [http://192.168.181.3/hoges]
Dependencies: called new_constants_in(Object)
Dependencies: New constants:
Dependencies: called new_constants_in(Object)
Dependencies: New constants:
Dependencies: called load_missing_constant(Object, "HogesController")
Dependencies: called require_or_load("/home/masayuki/work/rails/generator/test1/app/controllers/hoges_controller.rb", nil)
...(省略)...
Dependencies: called clear()
Dependencies: removing constant ApplicationHelper
Dependencies: removing constant HogesHelper
Dependencies: removing constant ApplicationController
Dependencies: removing constant HogesController
Dependencies: removing constant Hoge
Processing HogesController#new (for ::ffff:192.168.181.1 at 2009-07-25 20:24:47) [GET]
Rendering template within layouts/hoges
Rendering hoges/new
Completed in 20ms (View: 8, DB: 0) | 200 OK [http://192.168.181.3/hoges/new] |
Posted on July 8th, 2009 by masayuki | Filed in tips
昨日の続きを。
7. incompatible character encodings: ASCII-8BIT and UTF-8
- ASCII-8BIT外の文字を使っているソースの先頭に「#coding: utf-8」をつけた
- patchをあててみた
- <%= collection_select … %>で展開される文字がASCII-8BITの外だと「incompatible character encodings: ASCII-8BIT and UTF-8」 ← いまココ
以下のようなエラーがでます。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Showing app/views/layouts/application.html.erb where line #45 raised:
incompatible character encodings: ASCII-8BIT and UTF-8
Extracted source (around line #45):
42: </div>
43:
44: <div class="content" id="content">
45: <%= yield %>
46: </div>
47:
48: </body> |
DB(sqlite3)から取ってきた文字列に対してencodingメソッドを呼び出してみると…
1
2
3
|
@categories.each do |c|
p c.name.encoding
end |
“ASCII-8BIT”でした。database.ymlのencodingの指定が適用されないらしい。エンコーディングをforce_encodingで変えてやると、エラーは出なくなりました。
1
2
3
4
|
@categories.each do |c|
p c.name.encoding
c.name = c.name.force_encoding('utf-8')
end |
sqlite3のアダプタがNGなのかと思い、MySQL + MySQL/Ruby(2.8.1)で試してみましたが、やはり同じエラーになります。2.8.1はRuby1.9.1に対応していると書いてあるのですが、M17Nは未対応なのかな。
Ruby/MySQL 3.0.0 alphaの方曰く、
1
2
|
MySQL/Ruby と比べて遅かったり、非互換があったりしますが、Ruby 1.9 の M17N がちゃんと扱えるのはこれだけなので、Ruby 1.9
な人はこれを使ってみるのもいいと思います。 |
やはり厳しいみたい。
Posted on July 7th, 2009 by masayuki | Filed in dev, tips
これまで作ってきたものを、Ruby1.8.7+Rails2.1.1の環境からRuby1.9.1+Rails2.3.2に移行してみたいと思います。
1. rake rails:update:configsで失敗
1
2
3
4
5
6
|
masayuki@ubuntu-vm:~/work/rails/shrimp$ rake rails:update:configs
(in /home/masayuki/work/rails/shrimp)
rake aborted!
undefined method `>=' for nil:NilClass
/home/masayuki/work/rails/shrimp/Rakefile:4:in `require'
(See full trace by running task with --trace) |
config/boot.rbで、rubygemsのバージョンの取得がうまくできず、失敗しているようでした。
dummyのプロジェクトを作成し、そこからconfig/boot.rbをコピーしてrake rails:update:configsを実行。
2. gettextで失敗
1
2
3
4
5
6
7
|
masayuki@ubuntu-vm:~/work/rails/shrimp$ rake rails:update:configs
(in /home/masayuki/work/rails/shrimp)
rake aborted!
/usr/local/ruby-1.9.1-p129/lib/ruby/gems/1.9.1/gems/gettext-1.93.0/lib/gettext/iconv.rb:102: invalid multibyte char…
/usr/local/ruby-1.9.1-p129/lib/ruby/gems/1.9.1/gems/gettext-1.93.0/lib/gettext/iconv.rb:102: invalid multibyte char…
/usr/local/ruby-1.9.1-p129/lib/ruby/gems/1.9.1/gems/gettext-1.93.0/lib/gettext/iconv.rb:102: syntax error, …
puts Iconv.iconv("EUC-JP", "UTF-8", "ほげ").join |
gettextは事情があって—version ‘< 2.0.0’としてきたのですが、上記のエラーで動かないので、最新バージョン(2.0.4)をインストール。
3. gettext/rails→gettext_rails
|
gettext_rails provides the localization for Ruby on Rails-2.3 or later using Ruby-GetText-Package. |
とのこと。
4. config.cache_template_extensions
|
undefined method `cache_template_extensions=' for ActionView::Base:Class |
このメソッドはdeprecatedということで、コメントアウト。
5. app/controllers/application.rb→app/controllers/application_controller.rb
Rails2.3から、application.rbというファイル名が変更になっている為。リリースノートを読むと、rake rails:updateとすれば良かったらしい…。
6. jrailsの更新
jrailsはRuby1.9対応にする必要があります。
7. incompatible character encodings: ASCII-8BIT and UTF-8
- ASCII-8BIT外の文字を使っているソースの先頭に「#coding: utf-8」をつけた
- patchをあててみた
- <%= collection_select … %>で展開される文字がASCII-8BITの外だと「incompatible character encodings: ASCII-8BIT and UTF-8」 ← いまココ
Posted on July 6th, 2009 by masayuki | Filed in dev, tips
これまでずっとcoLinuxで開発をしてきました。が、ゲストOSとして使用してきたUbuntu7系のサポートが終わり、また容量もかなりギリギリになってきたので、この機会にUbuntu8に乗り換えようとcoLinuxのサイトに行ってみたところ、ダウンロードページが表示できませんでした・・・。
ということで、これを機にVMwareに乗り換えようと思い、VMware PlayerとUbuntu 8.04 LTSをダウンロード。
NATで外部に接続できるようにする為、ホストOSのネットワーク接続(「ローカルエリア接続)のプロパティ→「共有」タブにて、「VMnet8」(「ローカルエリア接続4」でした…)を選択し、「ネットワークのほかのユーザに、このコンピュータのインターネット接続をとおして接続を許可する」にチェック。この際、VMnet8のIP4のアドレスを書き換えてしまい、ゲストOS側から外に出ることができず大分はまりました。
VMware Playerがインストールされているディレクトリに「vmnetcfg.exe」というファイルがあり、これを実行するとNATサービスの設定の一部がわかるのですが、このサービスのアドレスがVMnet8の書き換える前のアドレスになっていた為、NATサービスに接続できなかったようです。
結局ホストOSとVMnet8のネットワークアダプタのアドレスを元に戻し、ホストOSから外部に接続できることを確認することができました。
Posted on July 5th, 2009 by masayuki | Filed in tips
前回プロファイリングの話で、当初はプロファイリングの終了をサーバの停止のタイミングで行いたいと考えていました。(結局その必要は無かったのですが)
その際に調べてみると、WEBrickはStopCallbackというコールバックを登録しておくことで、サーバ終了時に任意のコードを実行することができるようになっています。
ただ、rails-2.1.1のコードを見る限り、rails側からこのStopCallbackを登録する術が無いようで、結局うまい解決方法が見つからず、直接webrickのコードを修正してStopCallbackを登録できるようにしてみました。
1
2
3
4
5
6
7
8
9
10
11
|
@ubuntu:/usr/local/ruby-1.8.7-p72/lib/ruby/gems/1.8/gems/rails-2.1.1/lib# diff -u webrick_server.rb.org webrick_server.rb
--- webrick_server.rb.org 2008-09-15 19:57:55.000000000 +0900
+++ webrick_server.rb 2009-07-05 13:04:34.000000000 +0900
@@ -54,6 +54,7 @@
:ServerType => options[:server_type],
:BindAddress => options[:ip] }
params[:MimeTypes] = options[:mime_types] if options[:mime_types]
+ params[:StopCallback] = options[:StopCallback] if options[:StopCallback]
server = WEBrick::HTTPServer.new(params)
server.mount('/', DispatchServlet, options) |
rails側からStopCallbackを指定するには、RAILS_ROOT/config/environment.rbあたりに、以下のようなコードを記述します。
1
2
3
4
5
6
7
|
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
# ここから
OPTIONS[:StopCallback] = Proc.new do
puts "called StopCallback"
end
# ここまで |
script/serverでWEBrickを起動し、CTRL+cで停止すると、StopCallbackが呼ばれていることが確認できます。
1
2
3
4
5
6
7
8
9
10
|
masayuki@ubuntu:~/work/rails/shrimp$ script/server
=> Booting WEBrick...
=> Rails 2.1.1 application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2009-07-05 13:23:06] INFO WEBrick 1.3.1
[2009-07-05 13:23:06] INFO ruby 1.8.7 (2008-08-11) [i686-linux]
[2009-07-05 13:23:06] INFO WEBrick::HTTPServer#start: pid=2853 port=3000
[2009-07-05 13:23:08] INFO going to shutdown ...
called StopCallback
[2009-07-05 13:23:08] INFO WEBrick::HTTPServer#start done. |
ただし、プロセスをkillされるとどうにもなりませんが。
Posted on July 5th, 2009 by masayuki | Filed in tips
前回、ruby-profを使ってみたのですが、今回はperftools.rbというプロファイラを使ってみました。
もともと、
google-perftoolsというプロファイリングツールがあり、それをRubyで使用できるようにしたのがperftools.rb。現在はCpuProfilerのみですが、TODOにはHeapProfilerと記述されています。
まずはインストール。
|
gem install -s http://gems.github.com tmm1-perftools.rb |
サンプルコードで試してみます。
1
2
3
4
5
|
require 'rubygems'
require 'perftools'
PerfTools::CpuProfiler.start("/tmp/add_numbers_profile") do
5_000_000.times{ 1+2+3+4+5 }
end |
/tmpの下に、add_numbers_profile、add_numbers_profile.symbolの2ファイルが生成されます。これが結果ファイルになるので、pprof.rbというレポートツールを使用して内容を確認します。
1
2
3
4
|
Total: 134 samples
116 86.6% 86.6% 134 100.0% Integer#times
18 13.4% 100.0% 18 13.4% Fixnum#+
0 0.0% 100.0% 134 100.0% PerfTools::CpuProfiler.start |
これをrailsのアプリケーションに適用してみます。今回は、railsの初期化後からプロファイルを開始してみました。まず、RAILS_ROOT/config/environments/(実行するモード).rbに、以下を追記します。
1
2
3
4
|
config.after_initialize do
require 'perftools'
PerfTools::CpuProfiler.start("/tmp/shrimp_profile")
end |
あとはscript/server -e (実行モード)でサーバを起動し、アプリケーションを適当に操作した後、サーバを停止します。今回試してみた結果、以下のように出力されました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
$ pprof.rb --text /tmp/shrimp_profile
Total: 73 samples
22 30.1% 30.1% 26 35.6% Thread.start
15 20.5% 50.7% 15 20.5% IO.select
4 5.5% 56.2% 4 5.5% Module#constants
3 4.1% 60.3% 3 4.1% garbage_collector
2 2.7% 63.0% 2 2.7% SQLite3::Driver::Native::API.sqlite3_prepare
2 2.7% 65.8% 2 2.7% SQLite3::Driver::Native::API.sqlite3_step
1 1.4% 67.1% 1 1.4% String#sub
1 1.4% 68.5% 1 1.4% WEBrick::Cookie.parse
1 1.4% 69.9% 2 2.7% Array#map
1 1.4% 71.2% 1 1.4% ActiveRecord::Associations::AssociationProxy#initialize
1 1.4% 72.6% 1 1.4% Regexp#===
1 1.4% 74.0% 1 1.4% Proc.new
1 1.4% 75.3% 1 1.4% ActionController::Routing::RouteSet::NamedRouteCollection#define_url_helper
1 1.4% 76.7% 1 1.4% IO#write
1 1.4% 78.1% 1 1.4% Array#-
1 1.4% 79.5% 1 1.4% ActiveSupport::Callbacks::CallbackChain#find
1 1.4% 80.8% 1 1.4% Object#ticket_path
1 1.4% 82.2% 1 1.4% Object#detect
1 1.4% 83.6% 1 1.4% Object#options_for_select
1 1.4% 84.9% 1 1.4% ActiveRecord::Associations::AssociationProxy#load_target
1 1.4% 86.3% 49 67.1% Kernel#gem_original_require
1 1.4% 87.7% 1 1.4% Object#instance_variable_set
1 1.4% 89.0% 1 1.4% Time#initialize
1 1.4% 90.4% 1 1.4% ActionController::Routing::RouteBuilder#separator_pattern
1 1.4% 91.8% 1 1.4% Hash#[]
1 1.4% 93.2% 6 8.2% Module#local_constants
1 1.4% 94.5% 1 1.4% Hash#key?
1 1.4% 95.9% 1 1.4% Object#kind_of?
1 1.4% 97.3% 3 4.1% TicketsController#search_tickets
1 1.4% 98.6% 1 1.4% ActionController::AbstractRequest#ssl?
1 1.4% 100.0% 1 1.4% ActiveRecord::Base#column_for_attribute |
pprof.rbでは、結果からコールグラフをgif画像等で出力されることができます。今回、gif画像を生成するにたりGraphvizが必要ということで、別途インストールしました。
|
pprof.rb --gif /tmp/shrimp_profile > /tmp/shrimp_profile.gif |
上記コマンドを実行後、以下のgifが生成されました。

今回は初期化後から終了までの間をプロファイルしましたが、最初のサンプルコードのようにコードの一部をプロファイリングすることも可能なはずです。これは別の機会に試してみたいと思います。
Posted on July 4th, 2009 by masayuki | Filed in tips
productionモードの時だけ実行されるフィルタが必要になり、いつどこで定義するのが良いか調べてみましました。
githubを見て回ったところ、RAILS_ROOT/config/environments/production.rbで、config.after_initializeの中で定義すれば良いみたい。下記のコードで確認できました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
config.after_initialize do
require 'application' unless Object.const_defined?(:ApplicationController)
TicketsController.class_eval do
before_filter :start_action, :only => [:index, :search]
after_filter :end_action, :only => [:index, :search]
def start_action
logger.info "action start."
end
def end_action
logger.info "action end."
end
end
end |
Posted on June 26th, 2009 by masayuki | Filed in tips
capistranoでdeployするところまではできていたものの、アプリケーションの再読み込みについて調べるのが面倒で、ついついapacheをrestartしてました。
mephistoもpassengerで動かしているので、apacheを再起動せずに何とかならないものかと、調べてみました。
passengerのドキュメントを見ると、deploy後のアプリケーションのrestartについて以下のように記述されています。
1
2
3
4
5
6
7
8
|
Deploying a new version of a Ruby on Rails application is as simple as re-uploading the application files,
and restarting the application.
There are two ways to restart the application:
1.By restarting Apache.
2.By creating or modifying the file tmp/restart.txt in the Rails application’s root folder. Phusion Passenger
will automatically restart the application during the next request. |
ということで、deploy.rbに以下の記述を追加。
1
2
3
4
5
6
7
|
namespace :shrimp do
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
after :deploy, "shrimp:restart" |
以降、cap deployすると自動的に更新後のアプリケーションが再読み込みされます。
Posted on June 21st, 2009 by masayuki | Filed in tips
railsアプリのレスポンスがたまに物凄く悪くなることがあり、ruby-profを試してみました。
ruby-profのバージョンは現在0.7.3なのですが、railsアプリをプロファイルする際に、従来のproductionモードで実行した結果をログに出すアプローチから、プロファイリングしたい部分をtestで実行するアプローチに変わっているようです。今回はログに実行結果を出力する0.6.0を使うことにしました。
ruby-profをインストールします。
|
$ sudo gem install ruby-prof --version=0.6.0 |
インストールされたgemにrails-pluginというフォルダがあるので、それをプロファイリングしたいrailsアプリのvendor/pluginsの下に置きます。
1
2
|
$ cd /opt/shrimp/current/vendor/plugins/
$ cp -ipr /usr/local/lib/ruby/gems/1.8/gems/ruby-prof-0.6.0/rails_plugin/ruby-prof . |
アプリケーションをproductionモードで再起動後、リクエスト毎にlog/production.logに計測結果が出力されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
Processing TicketsController#index (for 59.156.119.10 at 2009-06-21 02:05:52) [GET]
Session ID: BAh7CDoLZmlsdGVybzoQUXVlcnlGaWx0ZXIJOgxAZXJyb3JzbzoZQWN0aXZl
UmVjb3JkOjpFcnJvcnMHOwd7ADoKQGJhc2VABjoWQGF0dHJpYnV0ZXNfY2Fj
aGV7ADoYQGNoYW5nZWRfYXR0cmlidXRlc3sAOhBAYXR0cmlidXRlc3sOIg9j
cmVhdGVkX2F0IhgyMDA4LTA5LTI4IDIzOjI0OjUzIhBwcmlvcml0eV9pZCIG
MyIPdXBkYXRlZF9hdEl1OglUaW1lDZFWG4D3ZcgWBjofQG1hcnNoYWxfd2l0
aF91dGNfY29lcmNpb25GIgl3b3JkIgAiDW93bmVyX2lkIgYxIgdpZCIGMSIQ
Y2F0ZWdvcnlfaWRpBiIMdXNlcl9pZCIGMSIOc3RhdHVzX2lkIgctMzoJdXNl
cmkGIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hI
YXNoewAGOgpAdXNlZHsA--ec1abaf426ea3d2f998bd9de5c10852c8499891a
Parameters: {"action"=>"index", "controller"=>"tickets"}
Rendering template within layouts/application
Rendering tickets/index
Completed in 0.36246 (2 reqs/sec) | Rendering: 0.05925 (16%) | DB: 0.03879 (10%) |
200 OK [http://xxxxx.wrap-trap.net/tickets]
[http://xxxxx.wrap-trap.net/tickets]
Thread ID: 3084116400
Total: 0.140000
%self total self wait child calls name
7.14 0.05 0.01 0.00 0.04 26 <Class::ActiveRecord::Base>#find_every
7.14 0.01 0.01 0.00 0.00 1 ActiveRecord::Transactions::ClassMethods#…
7.14 0.01 0.01 0.00 0.00 140 ActiveRecord::Associations::AssociationProxy#…
7.14 0.03 0.01 0.00 0.02 251 Hash#each
7.14 0.01 0.01 0.00 0.00 140 Ticket(id: integer, name: string, owner_id: integer,…
7.14 0.01 0.01 0.00 0.00 793 SQLite3::Driver::Native::Driver#column_type
7.14 0.01 0.01 0.00 0.00 212 ActionController::AbstractRequest#relative_url_root
7.14 0.01 0.01 0.00 0.00 47 Object#to_param
7.14 0.01 0.01 0.00 0.00 83 <Module::SQLite3::Driver::Native::API>#sqlite3…
7.14 0.01 0.01 0.00 0.00 2094 Kernel#is_a?
7.14 0.01 0.01 0.00 0.00 164 Symbol#to_sym
7.14 0.01 0.01 0.00 0.00 28 ActiveSupport::CoreExtensions::Array::Extract…
7.14 0.03 0.01 0.00 0.02 80 Integer#times
7.14 0.09 0.01 0.00 0.08 681 Kernel#send-2 |
なかなか便利なので、暫く仕込んだままにしておこうかと。
Posted on June 9th, 2009 by masayuki | Filed in tips
何かファイルのアップロードがおかしいな、とログを見てみたら、responds_to_parentメソッドが見つからない、というエラーが出てました。
vendor/plugins/responds_to_parent/rails/init.rbを確認したところ、
1
2
|
ActionController::Base.send :include, RespondsToParent
require 'parent_selector_assertion' |
となっており、問題無さそう…と思ったものの、ローカルの開発環境を見てみたらinit.rb→rails/init.rbへのシンボリックリンクが貼られていました。覚えにないなぁ…。
rails/init.rbは自動的に読みこまれないんでしたっけ?取り合えず気をつけておきます。
Posted on June 6th, 2009 by masayuki | Filed in tips
capstranoを使用してapacheを再起動し、アプリケーションにアクセスしてみると…
1
2
3
|
ActiveRecord::StatementInvalid (SQLite3::SQLException: unable to open database file: UPDATE "filters"
SET "updated_at" = '2009-06-05 01:47:06' WHERE "id" = 1):
... |
というエラーが発生しました。database.ymlに記載されているsqlite3のファイルパスは問題がないので困りましたが、調べていくにつれて、ジャーナルファイルの作成に失敗しているようでした。
ジャーナルファイルはsqlite3のデータベースファイルと同じ階層に作成されるのですが、railsのプロセスの所有者がそのディレクトリに対して書き込み権限を保持していませんでした。
これまでジャーナルファイルを意識してきませんでしたが、update文等を発行すると確かに生成されていました。
1
2
|
sqlite> begin transaction;
sqlite> update users set login='hoge' where id=1; |
1
2
3
|
$ ls -la shrimp*
-rw-r--r-- 1 masayuki dev 112640 2009-05-20 10:50 shrimp_production.sqlite3
-rw-r--r-- 1 masayuki dev 2056 2009-06-06 00:20 shrimp_production.sqlite3-journal |
http://www.sqlite.org/lockingv3.html#rollback
Any time a process wants to make a changes to a database file, it first records enough information in the rollback journal to restore the database file back to its initial condition. Thus, before altering any page of the database, the original contents of that page must be written into the journal. The journal also records the initial size of the database so that if the database file grows it can be truncated back to its original size on a rollback.
The rollback journal is a ordinary disk file that has the same name as the database file with the suffix “-journal” added.
Oracleでいうところのロールバックセグメントのようなものなのでしょう。ディレクトリに対して書き込み権限を付与したところ、前述のエラーはでなくなりました。
Posted on June 5th, 2009 by masayuki | Filed in dev, tips
さくらで動かしていたアプリケーションを移行しているのですが、capifyされたrailsのアプリケーションについては、capistoranoで移行してみました。
まずは、
|
$ apt-get install subversion |
でsvnを使用できるようにします。
次に、deploy.rbを移行先の環境に合わせて書き換えました。その後、
としたところ、
1
2
3
|
..
** [wrap-trap.net :: out] svn: Can't make directory '/opt/shrimp/releases/20090604151717': Permission denied
.. |
と怒られてしまいました。
ディレクトリの作成で失敗しているようなので調査してみると、確かに権限の問題はあるようですが、そもそも/opt/shrimpというディレクトリ自体も無い…。もうちょっと調べてみると、いきなりdeploy:coldが間違っていたようです。最初はdeploy:setupを行う必要がありました。
1
2
3
4
5
6
7
8
9
10
|
$ cap deploy:setup
* executing `deploy:setup'
* executing "sudo -p 'sudo password: ' mkdir -p /opt/shrimp /opt/shrimp/releases /opt/shrimp/shared
/opt/shrimp/shared/system /opt/shrimp/shared/log /opt/shrimp/shared/pids && sudo -p 'sudo password: '
chmod g+w /opt/shrimp /opt/shrimp/releases /opt/shrimp/shared /opt/shrimp/shared/system /opt/shrimp/
shared/log /opt/shrimp/shared/pids"
servers: ["wrap-trap.net"]
[wrap-trap.net] executing command
** [out :: wrap-trap.net]
command finished |
その後、再度deploy:coldを実行したものの、やはりmkdirでPermission deniedは変わらず。権限がないということで色々と調べてみたところ、deploy:setup後にchownを実行してディレクトリの所有者を変更すれば良いことがわかりました。deploy.rbに以下を追加して再実行し、ディレクトリの所有者を変更します。
1
2
3
4
5
6
7
|
set :runner, 'masayuki'
set :group, 'users'
set :use_sudo, true
...
after 'deploy:setup' do
try_sudo "chown -Rf #{runner}:#{group} #{deploy_to}"
end |
「try_sudo」というコマンドは知らなかった。というかcapistranoのコマンドにどんなものがあるか知らない。そういったドキュメントを見たことがないのですが、rdoc見るしかないのかな。
http://lee.hambley.name/capistrano-2.5.0/rdoc/
ちなみに、deploy先の環境に合わせて、after_symlinkでファイルを上書いています。これが普通のやり方なのかわかりませんが。
1
2
3
4
5
6
7
8
|
task :after_symlink do
%w{database.yml envrinment.rb}.each do |f|
run "cp -f #{shared_path}/files/#{f} #{current_path}/config/#{f}"
end
%w{production.rb}.each do |f|
run "cp -f #{shared_path}/files/#{f} #{current_path}/config/environments/#{f}"
end
end |
passengerとの連携はまだできてないので、後日試してみたいと思います。
Posted on May 30th, 2009 by masayuki | Filed in tips
久々にgithubを見たら、pull requestが来ていました。userstampのfork元が修正され、それに伴ってfork先にpull requestが発行されたようです。メール見てませんでした。
他の人の変更を取り込んだことが無かったので、Guides: Pull Requestsを見ながら差分をmergeしてみます。
まず、今回の変更が行われたリモートリポジトリを登録しようとしたところ、
1
2
|
$ git remote add -f korobkov git://github.com/korobkov/userstamp.git
fatal: Not a git repository |
と怒られてしまいました。以前作業したgitフォルダとは別のフォルダで作業しようとした為、.gitフォルダが無くてNGのようです。git initしないといけないらしい。
1
2
3
4
5
6
7
|
$ git init
Initialized empty Git repository in /home/masayuki/work/rails/tmp/test/.git/
$ ls -la
合計 12
drwxr-xr-x 3 masayuki dev 4096 2009-05-30 16:55 .
drwxr-xr-x 4 masayuki dev 4096 2009-05-30 16:55 ..
drwxr-xr-x 7 masayuki dev 4096 2009-05-30 16:55 .git |
.gitフォルダができました。remote addはうまくいったので、ファイルを取り込む為のbranchを作成します。
1
2
|
$ git checkout -b korobkov/master
fatal: ou are on a branch yet to be born |
また怒られてしまいました。READMEというファイルを作成しcommitした後、再度試してみると、
1
2
|
$ git checkout -b korobkov/master
Switched to a new branch "korobkov/master" |
うまくいきました。次に、先ほどのbranchにファイルを取り込もうとしたところ、
1
2
|
git pull korobkov master
fatal: empty ident not allowed |
またまた怒られてしまいました。configに、user.nameの指定が無かった(user.namaになっていた)為でした。
1
2
3
|
$ git config --global user.name "masayuki038"
$ git pull korobkov master
Automatic merge failed; fix conflicts and then commit the result. |
取り込めたものの、READMEファイルがconflictしました。修正して、
|
$ git commit -a -m"update merge" |
でコミット。
次に、以前forkして変更を加えたremoteリポジトリを登録します。この際、remoteリポジトリの場所にPublic Clone Urlを指定してしまうと、pushする際に、
1
2
|
$ git push origin master
You can't push to git://github.com/user/repo.git |
とエラーがでます。その為、remote addにはYour Clone Urlを指定します。
|
$ git remote add origin git@github.com:masayuki038/userstamp.git |
branchをmasterに切り替えます。
1
2
3
4
5
|
$ git branch
* korobkov/master
master
$git checkout master |
あとはmasterにpullし、branchにpullしたファイルをmergeします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$ git pull origin master
$ git merge korobkov/master
warning: refname 'korobkov/master' is ambiguous.
warning: refname 'korobkov/master' is ambiguous.
Auto-merged README
Merge made by recursive.
README | 8 ++--
lib/stampable.rb | 54 ++++++++++++++++--------------
test/compatibility_stamping_test.rb | 2 +-
test/helpers/functional_test_helper.rb | 10 +++--
test/helpers/unit_test_helper.rb | 58 ++++++++++++++++---------------
test/stamping_test.rb | 2 +-
test/userstamp_controller_test.rb | 24 +++++++------
7 files changed, 84 insertions(+), 74 deletions(-) |
自動的にcommitされるらしく、リモートリポジトリにpushして完了です。
1
2
3
4
5
6
7
|
$ git push origin master
Counting objects: 50, done.
Compressing objects: 100% (22/22), done.
Writing objects: 100% (38/38), 7.78 KiB, done.
Total 38 (delta 21), reused 25 (delta 14)
To git@github.com:masayuki038/userstamp.git
af36e03..7df7841 master -> master |