Hatena::ブログ(Diary)

Kazzzの日記 このページをアンテナに追加 RSSフィード

2009-10-27

[][]アップグレードダウン


RubyMineの2.0βを試したくて、暫くぶりでRailsで書いたアプリケーション(scaffold)を起動したら、何故かエラーが出て動かない。どうやらRailsを2.3に上げたのが原因なのだが、そんな違いがあったっけか。

セッションキーの設定

`ensure_session_key': A key is required to write a cookie containing the session data. Use config.action_controller.session = { :key => "_myapp_session", :secret => "some secret phrase" } in config/environment.rb (ArgumentError)

と起動時に怒られる。

親切なことに、どのスクリプトに設定を追加すれば良いかメッセージが表示されているので、その通りに修正する。


application.rb ファイル名変更問題

起動はしたが、コントローラを呼び出す際に例外発生
NameError (uninitialized constant ApplicationController):
  app/controllers/people_controller.rb:1


ApplicationControllerが見つからない。
どうやらapplication.rbはapplication_controller.rbに名前が変わったらしい。

ファイル名を変更。


これで完了。generateで吐かれたコードだし、やはり違いがあるんだな。

2009-08-27

[][][]Heroku


Heroku

Webブラウザを使ってRailsの開発ができる、ということで話題になったHeroku Gardenだが、本家のHerokuはRuby on Railsをホスティングする、いわば"Rails-PaaS"(といってもいいだろう)マルチテナントサービス

バックエンドにはAmazon EC2を使っているらしいが、個人的にはGoogleなんかよりもこちらを使って何かしたいな。

2009-04-22

[][]radio_buttonの:checked属性にブール式が可能になっていた件



バージョン幾つからか分からないのだが、erbに以下のようにform_forでHTML Formを書く場合、

<% form_for :form, :url=>{ :action => :query}  do |f| %>
  <%= f.radio_button :gender, :male, :checked=> (@form.gender == :male || @form.gender == nil) %>男
  <%= f.radio_button :gender, :female, :checked=> (@form.gender == :female ) %>女
<% end %>

元々のRailsの実装ではBuilderのradio_buttonメソッドの:checkedオプションはブール式を使うとそのまま結果が属性に設定されてしまうので、変換されるHTMLは

<input name="form[gender]" id="form_gender_male" type="radio" CHECKED="true" value="male"/>男
<input name="form[gender]" id="form_gender_female" type="radio" CHECKED="false" value="female"/>女

となってトホホだったはずだが、Rails2.3では

<input name="form[gender]" id="form_gender_male" type="radio" CHECKED="checked" value="male"/>男
<input name="form[gender]" id="form_gender_female" type="radio" value="female"/>女

と、ちゃんと変換される。ブール式を使えるのはなにかとありがたい。

2009-04-16

[][]ActiveRecord(oracle_enhanced_adapter)のモンキーパッチ


oracle_enhanced_adapterのtablesメソッドは他のConnectionAdapter同様にテーブルしか列挙しないため、Oracleの既存のView(ビュー)、Synonym(シノニム)をActiveRecordで活用できない。

def tables(name = nil) #:nodoc:
  select_all("select lower(table_name) from all_tables where owner = sys_context('userenv','session_user')").inject([]) do | tabs, t |
    tabs << t.to_a.first.last
  end
end

是非は別にして、スキーマからはテーブルだけではなく、ビューとシノニムも列挙する、以下のようなtableメソッドに対してのモンキーパッチを書いてみたのだが※、

  • oracle_enahnced_adapter_view_and_synonym.rb
require 'active_record/connection_adapters/oracle_enhanced_adapter'
module ActiveRecord module ConnectionAdapters class OracleEnhancedAdapter < AbstractAdapter def tables(name = nil) select_all(<<-END_SQL select name from ( select lower(table_name) as name, owner from all_tables union all select lower(view_name) as name, owner from all_views union all select lower(synonym_name) as name, owner from all_synonyms ) where owner = sys_context('userenv','session_user') END_SQL ).inject([]) do | tabs, t | tabs << t.to_a.first.last end end end end end

※SQLに関してはあまり自信が無い。もっと効率の良い書き方があるのかもしれない

このようなRailsのコンポーネント(ActiveRecord)に対してのモンキーパッチはどこに配置するのが適当なんだろうか。

試しにemvironment.rbにrequireを書いたんだがdb:schema:dumpを実行すると接続が確立してないぞと怒られてしまった。

E:\www>rake db:schema:dump
(in E:/www)
rake aborted!
uninitialized constant ActiveRecord::ConnectionNotEstablished
(See full trace by running task with --trace)

なるほど、establish_connectionが呼ばれる際にはもう既に読み込まれている必要があるのか。

new_rails_defaults.rbに書くことで上手く動くことを確認したんだが、そもそもこのスクリプトに手を入れるのが正しいのかもわからん。

2009-04-11

[][]Ruby 1.8.6-p368


Ruby 1.8.6-p368 リリース

早速試してみようとビルドして(ビルド自体は1.8.7系とは違い、問題無し)Railsを起動してみたのだが、1.8系がOKのはずのMongrelが動かん。

E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/mongrel-1.1.5-x86-mswin32-60/lib/http11.so: 126: 指定されたモジュールが見つかりません。   - E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/mongrel-1.1.5-x86-mswin32-60/lib/http11.so (LoadError)
	from E:/ruby1.8.6_p368/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
	from E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:156:in `require'
	from E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:521:in `new_constants_in'
	from E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:156:in `require'
	from E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/mongrel-1.1.5-x86-mswin32-60/lib/mongrel.rb:12
	from E:/ruby1.8.6_p368/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
	from E:/ruby1.8.6_p368/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
	from E:/ruby1.8.6_p368/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:156:in `require'

嫌な予感がしてhttp11.soの依存性を調べてみると、msvcrt-ruby18.dllの欠落エクスポート。
ランタイムはRubyのビルド時に作られているはずだが、とruby/binを見て見るとあるのは
msvcr80-ruby18.dll

欠落エクスポートは
msvcrt-ruby18.dll

微妙に違う。MakeFileが変わっていたのか....

追記: これって拡張ライブラリィを使っているgemは全滅(ビルドし直し)ということだよな

2009-04-09

[][]form_tagのオプションとブロック


Railsでモデルと関連の無いところでフォームのデータを取ろうと思い、以下のようにform_tagを記述したのだが

<%= form_tag :action => :query , { :name => "hogeForm", :id => "hogeForm"} %>

エラーが出てしまう。
compile error
/app/init.html.erb:2: syntax error, unexpected ';', expecting tASSOC
...eForm", :id => "hogeForm"} ; @output_buffer.concat "\n    ...
                            ^

form_tagメソッドのシグネチャを調べてみたのだが、
def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)

と、先頭のパラメタもハッシュなので、この(第2パラメタ以降の指定がある)場合"{}"(ブレース)は省けないんだったな。
そこで、以下のように書き換えたが、
<%= form_tag {:action => :query} , { :name => "hogeForm", :id => "hogeForm"} %>

相変わらずエラー。
compile error
/app/init.html.erb:2: syntax error, unexpected tASSOC, expecting '}'
;  form_tag {:action => :query} , { :name => "hogeF...
                       ^
/app/init.html.erb:2: syntax error, unexpected ',', expecting kEND
...form_tag {:action => :query} , { :name => "hogeForm", :id ...
                              ^

うーん。なんだろうと小一時間悩んだが、ちゃんとFAQに掲載されていることだった。
p {}で何も表示されません - Ruby FAQ

なるほど、"{}"ブレースがハッシュではなくブロックの開始と判断されているのか。

ということで更に修正、hogeFormもシンボルで書けるようなので修正。
<%= form_tag ({:action => :query} , { :name => :hogeForm, :id => :hogeForm }) %>

やっと正しくHTMLに変換された。

<form action="/app/query" id="hogeForm" method="post" name="hogeForm">

Rubyはメソッドパラメタを括る括弧が省けるので、メソッドがまるでカスタムなタグのように書ける。※それが嬉しくて、調子にのってしまったようだ。

※言語内でDSLを実現することが出来るため、個人的にはRubyの文法で最も気にいっている仕様の一つだ。

2009-03-31

[][]カスタムタグ(のようなもの)


Java-JSPでは「カスタムタグ」と呼ばれる独自のタグを定義することでビュー中のコンポーネントをJavaで実装することができた。

<%@ taglib uri="/WEB-INF/hogeb.tld" prefix="hoge" %>
<hoge:fooCustomTag property="bar"/>

これと同じことをRailsで実現しようとする場合、どのような方法が良いのだろうといろいろ調べたのだが、そんな難しく考えることではなかったようだ。

単にビューのヘルパーをビューから呼び出すだけで良いらしい。
Railsのビューヘルパー - [ThinkIT] 第3回:JSFとRailsで比較(後編) (2-3)

であれば、JSPでガシガシと書いていたカスタムタグだってJSPのスクリプトレットで、コンテキスト中のメソッドを呼び出すだけで良かった訳だが、どうしてその当時にそうはならなかったのだろうなあ。(ASPと初期のJSPのスクリプトレットを嫌悪する空気がそうさせた?)

あと、少し違うがカスタムタグとして実装することもあった、例えばWindowをオープンするスクリプト(javascript)を出力制御するようなタグ 'window_open_script'を作る場合、Railsならば

  • 同様にビューヘルパーを使う
  def window_open_script( options = {}, function_name = "window_open")
    javascript_tag do 
      page = "function " + function_name + "(url, name, width, height)"
      page << "{\n"
      page << "   if (!lock()) return false;\n"
      〜略
    end
  end

  • ビュー中に直接記述する
<%= javascript_tag <<-END
    function windowOpen(url, name,  width, height) {
        if (!lock()) return false;
    〜略
  END
%>

両方法とも部分テンプレートとして組込むこともできる。

などがあるが、どれがベストなんだろうな。いろいろ書けてしまうってのも悩ましい。