Categories
open all | close allTags
Flash | 認証 | 国際化 | テスト | モデル | アクセス制御 | タグ | rake | フォーム | JustPosted | パソコン | スキンエンジン | Subversion | RESTful | CSRF | Migration | 名称 | ドキュメント | Aptana | デュアル・コアSearch
落ち穂拾い
Configテーブルで初期設定が必要なデータなど,一からインストールする場合に必要になる項目を調べて備えています。サイト名とURLはインストーラで設定するようにしました。インストーラ難しかった
実際に動かしてみると,難問にぶち当たりました。DBのテーブルがない状態ではWebが起動しないのです。いや実際には設定を変えれば起動できるのですが,これだと今度はマイグレーションを実行したりといったことができません。結局言語設定とサイトオーナー設定の部分だけになってしまいそうです。これだとあんまりメリットないけど,サイトオーナー設定はやらないと困るので一応この機能は生かしておきます。
プレース・ホルダ機能を組み込む
RailsのActiveRecordにはプレース・ホルダの機能があります。例えば検索条件を指定するときに["name=?", yourname]で?のところを変数yournameの内容で置き換えたり(実際にはクオートの処理なども行われます),さらには["name=:name", {:name=>yourname}]のようにハッシュをキーとして渡して置き換えることもできます。こういった機能はアプリケーションの中でも使いたくなるのですが,残念ながらAPIとして表には出てきていないようです。調べ方が悪いだけかもしれませんが,おそらくクオートの処理や型の判断などSQLに依存した部分が多いからではないかと思っています。
文字列の国際化の処理をするとき,一部を変数として扱いたいときがあります。例えば英語では「Welcome, Andy!」と表示するところを日本語では「ようこそAndyさん」にするといったときです。このときに変数部分を維持したまま変換をする方法を考えると,プレース・ホルダが必要になります。今の例で言えば「Welcome :name!」となっているところを「ようこそ:nameさん」に変換して変数に置き換えるわけです。というわけで車輪の再発明になることを恐れつつ,そんな面倒なコードでもないので(というか極めてシンプル),組み込んでみました。
以下がコード。
def la(str, arg=nil)
if arg
s = FoodynI18n.text(str.to_s, 'admin')
s.gsub(/\:([0-9A-Za-z_]+)/) {arg[$1.to_sym]}
else
FoodynI18n.text(str.to_s, 'admin')
end
end
まず,国際化の処理で文字列を変換します。その後で変数の処理をします。置き換えるところが定数でないと,PHPだとコールバックさせたりしないといけないですが,Railsではブロックが使えるのでシンプルに記述できます。
検証メソッドはすばらしい
前回書いた中間テーブルのことは,考えてもしょうがなさそうなのですぱっとあきらめ,中間モデルを操作する形で書いています。引き続き管理画面のユーザー管理周りを書いていますが,ここはあまりいい加減にしておくと,不正なユーザーを作り出す元になりかねないので,アクセス権などちょっと注意しながら書いています。
特に,保存時に不正な値が入っていたときの処理もやっていますが,Railsにはvalidates_~~という検証用のメソッドが豊富に用意されているので,かなり簡単に実現できます。Railsで一番便利だなあと思うのはやはりActiveRecord周りです。
原因究明>泣きたくなった【追記あり】
InvalidAuthenticationToken問題の解決がやっと見えてきました。簡単なサンプルプログラムを作って,そこでの動作といちいち比較するというかなりしんどいデバッグでした。問題点の一つはコントローラでlink_toをしているところ。実はコントローラではlink_toはサポートされておらず,ビューにしかこのメソッドはありません。で,自分でも忘れていたのですが,これを「self.class.helpers」にdelegateで渡すといった記述をしていました。ところが,これだとビューはビューでも新しいビューを作ってそれに渡すことになり,そこでコントローラとの連携が切れてしまっていたのでした。デバッグ中に調べていくとコントローラの@templateというインスタンス変数がビューを格納していたので,それに渡すように変更しました。
次に,それでも途中で,CSRF対策機能を使うかどうかをチェックするprotect_against_forgery?というメソッドが何も実行しないで返ってきてしまう。これにすごく悩んだのですが,実はこれも自分のせいであることが判明。ヘルパーになぜかこの名前のメソッドを作っており,中身が空っぽだったのです。きっと,自分で代わりになる機能を入れようとか考えていたのだろうと思うのですが全く記憶にありませんでした。中身が空のメソッドはデバッガが飛ばしてしまうため,そこに行っていることに気付きませんでした。プロジェクト内に検索をかけてようやく発見。
これだけでおおよそ4時間。疲れました。しかも全部自分のせいだし…
これでほかのところも動いてくれるといいのですが。
【追記】
これでほかのフォームにもCSRF対策用のフィールドが自然に入るようになりました。こりゃ確かに検索しても原因が分からないのは当然です。今後の作業は大分スムーズになるのではないかと思います。
で,結局
fields_forとcheck_boxの組み合わせはあまりにも複雑になってしまうため,シンプルなcheck_box_tagで出力するほうがよほどまし,ということになってしまいました。泰山鳴動して鼠一匹。ファーム要素がセンタリングされるのが気持ち悪いのですが,世の中にCSSほど苦手なものはないので,しばらく解決する気なしです。
ああ徒労。
インライン・テンプレート
インライン・テンプレートの機能,動くようになったのですが,今の「ネストなしパーサー」だとインラインでテンプレート書くときに<%%>が使えないので<::>に書きなおす必要があります。やはりこれだと面倒なので,ネスト付きパーサーに切り替えることを画策中です。
ただ,単純に切り替えただけではさすがにエラーが…。ちゃんとテストしていないメソッドなので当然ですが。しばらくバグ取りに時間がかかりそうです。
それと,このネスト付きパーサーを考えたときは,ネストの内側も全部解釈実行することを前提にしていたのですが,考えてみたら内側は別のパーサー(例えばスキン変数の内側はテンプレートのパーサーが扱うべき)で実行するのが普通なので,そのあたりの処理も変えないといけません。例えばifの解釈もネストできるのですが,そこはオーバースペックでしょう。
Nucleusの開発合宿に参加しました
Nucleusの開発合宿に行ってきました(詳しくはこちら)。とはいえ二泊三日のうち中日の日帰りという一部の参加でした。Foodyn CMSについてはこのブログにいろいろ書いてはいますが,見ていない人も多いだろうし,情報がまとまっていないので,この機会にどういうものだか理解してもらおうと,時間を取ってもらってプレゼンさせてもらいました。前の記事のプレゼンはそのための資料です。
午前中に1回と,見逃した人用に夕食後に1回,計1時間近く使わせていただきました。ありがとうございました。これが何かのきっかけになればと思います(Sourceforge.netのDevelopersは一人増えました。^^)。
また,ページスイッチの部分を実装しました。一つのページの中に複数の切り替え用スイッチ(例えば一つはメインブログ,もう一つはサブブログの切り替え用)を置けます。実装は案外苦労しましたが,割と面白い機能になったかと思います。
トップ・ページとレイアウト機能に対応しました
サイト・トップにアクセスしたときに「main」スキンがあったら,そちらを表示する機能と,レイアウト機能,デフォルト・スキン・パートの機能を実装しました。これらを使うと最低限のスキンを作ることがこれまでよりかなり簡単になるだろうと思います。
インライン・テンプレートの機能を加えれば,スキン編集一つだけでも済ませられるようになります。