忍者ブログ
ブログツール、2007/11/06作成
[8] [9] [10] [11] [12] [13
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

アンケートを収集するプログラムを作成中のこと。
日時を入力する設問を作ってみた。

パラメータで年月日時分秒を渡して、Timeオブジェクトを作成する。
モデルクラスの中で日付の正当性チェックするために、ArgumentErrorをrescueして、引っかかったら再入力させるように実装。

テストで、誕生日を聞く設問を作って、自分の誕生日を入れてみると、ArgumentErrorが発生して再入力を促される。
ちなみに1969年の生まれなんだけど、1970以降を入れてみるとOK

むむ?と思ってirbを立ち上げて、Time.localで試しに1969年以前を作ろうとすると、同じくtime out of rangeが返ってくる。
どうやらエポックタイム以前を入力するとout of rangeが返ってくるらしい。
ちなみに環境はWindowsXP Home。rubyのバージョンは1.86。

試しにLinuxのirbでやってみると、こっちはエラーが返ってこない。
一寸調べてみるも、謎のまま。

まあ、本番環境なら問題ないならいいか、とこの問題は後回しにする。

DateTimeクラスなら大丈夫かと思ってやってみたらこっちは大丈夫。
DateTimeが推奨なのかしらん。
PR
先日書いたエントリで、パラメータに配列やハッシュを格納する方法を書いた。
で、複雑な使い方をしたら、日本語のエンコードでハマった。

barを生成する情報を持つhogeインスタンスの配列からチェックボックスで選択して追加しようとする。

view
<% index = 0%>
<% hoges.each do |hoge| %>
<%= check_box_tag "index[]", index %>
<%= hidden_field_tag "hoge[][fuga]", hoge.fuga %>
<%= hidden_field_tag "hoge[][piyo]", hoge.piyo %>
<% end %>
<%= link_to_remote "チェックしたHogeを加える",
:update=>'hoge_column',
:submit=>'hoge_colunm,
:url=>{:contoller=>'bar', :action=>'add_bar' } %>
controller
def add_bar
if params[:index]
params[:index].each do |index|
bar = Bar.new
bar.fuga = params[:hoge][index.to_i][:fuga]
bar.piyo = params[:hoge][index.to_i][:piyo]
end
end
end
と、こんな風にしてみた。
実際にはもうちょっと複雑だけど。

で、このパラメータに日本語が入ったときにエンコード問題が。

いろいろ試行錯誤してみた。

上の例でいうと、hoge.fugaが「動画共有」だったとすると、
コントローラでparams[:hoge][index.to_i][:fuga]をみると、
%25E5%258B%2595%25E7%2594%25BB%25E5%2585%25B1%25E6%259C%2589

む、これはURLエンコードがデコードされてないな、と思って、
URI.decode(params[:hoge][index.to_i][:fuga])してみると、
%E5%8B%95%E7%94%BB%E5%85%B1%E6%9C%89

ええ~!?
で、もしかすると、と思い、さらにデコードしてみる。
URI.decode(URI.decode(params[:hoge][index.to_i][:fuga]))
動画共有

うむむ…何で2回もエンコードされてるんだ?orz
よく忘れちゃうのでメモ。

フォームヘルパのform_tagで、
<%= form_tag :contorller=>'hoge', :action=>'fuga' %>
</form>
とやると閉じタグが気持ち悪いので、do~endでやるわけだけど、そのときの注意

  1. <%= %>はやっちゃだめ。
  2. form_tag()の括弧は省略するとハマる。オプションの{}ブレースも省略しない方が吉。

こんな感じ
<% form_tag( {:controller=>'hoge', :action=>'fuga', :piyo_id=>@piyo} ) do %>

<% end %>
AR.findの:includeオプションでハマる。

これまであまりにパフォーマンス無視で作ってきたのを反省して、SQLの発行回数を減らすために:includeオプションを多用してみた。
そしたら、Modelクラスで:order宣言しているときにSQLエラー発生。
エラーをみるに、order指定しているカラムは使えん、とのこと。

はじめ、:order指定するためのカラム名を安直にorderにしてしまったため、SQLの予約語とかぶったんだと思い、シングルクオートで囲んだりいろいろやってみるもいずれも失敗。
さらにカラム名をdisplay_orderとかにしてみてもだめ。

結局、回避策はModelクラスの :orderオプションにテーブル名のプレフィックスをつけることでした。orz
こんな感じ

class Hoge
has_many :fugas, :order="fugas.display_order"
end

class Fuga
belogns_to :hoge
end
こうしたものの、多重has_many関連の途中だと失敗しちゃう。
例:
class Hoge
has_many :fugas, :order=>'fugas.desplay_order'
end

class Fuga
belogns_to :hoge
has_many :piyos, :order=>'piyos.display_order'
end

class Piyo
belongs_to :Fuga
end
このとき、
コントローラで
hoge = Hoge.find(id, :include=>{:fuga=>:piyo})
とやったときは問題ない。
fuga = Fuga(id, :include=>:piyo)
とやったときもOK。
ところが、
hoge = Hoge.find(id, :include=>{:fuga=>:piyo})
とやって、
fuga = hoge.fugas.find(fuga_id, :include=>:piyo)
とやるとSQLエラーが。

ARのソースでも読めばわかるんだと思うけど、なかなかそこまでの根性が入りまへん。
あきらめて結局、
fuga = Fuga.find(fuga_id, :include=>:piyo)
とやってしまった。

とほほ。
railsを使っていて、アクションのパラメータ(paramsで渡されるやつ)にハッシュや配列を使いたいときがある。
これまでどうやって使えばいいのかわからないので適当に回避していたけど、ようやくやり方がわかった。

わかってみれば実に簡単。(^^;
Viewファイルのinput系ヘルパを使うときの第一引数にそのまんま書いてやると反映することが判明。

:hoge_array.rhtml
<%= hidden_field_tag "hoge[]", "fuga1" >
<%= hidden_field_tag "hoge[]", "fuga2">

params[:hoge] ->["fuga1", "fuga2"]

とまあ、こんな感じ。

hidden_field_tagをcheck_box_tagにしてやれば、選択項目のみを配列で取得できるようになる。
まあ、なんて便利な。


ハッシュがほしいときにはこうする。
:hoge_hash.rhtml
<%= hidden_field_tag "hoge[fuga]", "FUGA1" >
<%= hidden_field_tag "hoge[piyo]", "PIYO2">

params[:hoge] -> {:fuga=>'FUGA1", :piyo=>"PIYO2"}
前のページ   
ついめ~じ
ブログ内検索
フリーエリア
サニーカメラ
Powered by Ninja Blog    template by Temp* factory    icon by MiniaureType

忍者ブログ [PR]