Archive for January 5th, 2011

Multi-siteをWordPress 3.1-RC2にアップデートしてはまって解決

coreserverでWordpressをMulti-site運用している。
もともとWPMUを入れていて、WP3にアップデート、現在に至る。

/wp-admin/ に入ろうとすると &reauth=1 に飛ばされて永遠にログインできない事態に巻き込まれ、泥臭く調査してどうにか解決した。

1. ResponseのSet-Cookieヘッダを確認
まずFirebugの用意。ChromeとかIEのツールはリダイレクトを追えないようだ(できるの?誰か教えて!)
まあ、HTTPを見られればなんでもいいです。
で、いっちゃん最初のPOSTからのResponseを確認する。Set-Cookieヘッダ内に domain=とpath=があるはず。僕の場合はこの2つがおかしくてログインに失敗していた。

2. wp-config.phpから、define(“〜〜_CURRENT_SITE”, 〜〜) を削る
これは確か、WPMUあたりでマルチサイト化を始めるにあたり、「wp-config.phpにこれを書いとけよ!」と指示されていたものなのだが、こいつがあるとSet-Cookieのdomainとpathがここに書いた設定に強制的になってしまう。詳しくは wp-includes/ms-load.php の wpmu_current_site() を見るといい。

3. wp_siteテーブルに子サイトの情報を書き込む
これ、なぜか手作業。RC2のバグかもしれん。報告した方がいいのかな。。。そわそわ。

4. wp-include/ms-load.phpを修正
なおらん!どう考えてもおかしい!ということでけっこう強引に直してしまった。
この修正はあんま自信無いです。(動くけど、方針に合ってないかも)
function wpmu_current_site() の真ん中の辺り。

if ( $current_site ) {
	$path = $current_site->path;
	$current_site->cookie_domain = $cookie_domain;
	define('COOKIE_DOMAIN', '.' . $current_site->cookie_domain);
	define('COOKIEPATH', $path);
	return $current_site;
}

2つのdefine分が追加箇所。

とりあえずこれで動いてます。たぶん。

ControllerとViewは対応しなくてもいいってさ!

Railsのいくつかのチュートリアルをこなし、いくつかのオンラインドキュメントを読んで、MVCの使い分けはだんだんわかってきた。しかし、はたと立ち止まってしまったことがあったので記録。

ごく簡単な名簿アプリケーションを作る。2つのmodel、 Group と Person があるとする。
Person はいずれか1つの Group に関連づけられるものとする。

/:id を GroupController へ繋ぎ、所属する Person のリストが表示されるものとする。
/:id/:person_id をPersonControllerへ繋ぎ、Person の各種属性を表示編集できるようにする。
Groupを新規作成するための form を / とか /new とかに置く。
ここまではまあ、普通。

Person を新規作成するための form は、どうしようか。
教科書的に考えれば、 /:id で表示されるリストの末尾とかに「人を追加」ってなリンクを用意し、これが /:id/new かなんかに飛んで PersonController#new で承る、と、こうなる。

しかしもし、Person の作成に必要な情報が3つとか4つだったら、「人を追加」なんて悠長なことを言うより、とっととそこにFormを埋めてしまえという気分になる。

ハンドル 生年
大久保 kuboon 1980
猫村 catchocolate 1989
追加

こんなかんじぃ?

RailsのMVC哲学からちょっと外れたような気もするが、UIの最適化を考えれば自然の成り行きである。
さてさて、次が問題だ。

このformのPOST先をどうしよう?

formをGroupControllerで生成したとはいえ、これから生成しようとしているのはPersonであるから、PersonControllerで処理してやりたい、というのが人情というものである。
実際そのような記述は可能であるし、一見何の問題も無いような気が、少なくとも僕はしたのだが。。。
Validationめんどい。。。
中止!中止!

明らかにRailsは、formとそのPOST先が同じControllerであることを要求している。
POST先を別のControllerにしちゃあまずいのである。

と、いうことがわかった。

さーてどうするんだ。「この人でなし!」と言われるのを覚悟でGroupControllerでPersonを生成しちゃうのか、それとも、やはりイニシエの掟に従って、GroupController 側は「人を追加」リンクのみに留めておけということなのか、はたまたajaxでformを表示しちゃうようなウルトラCが既に常套となっているのか。

と、一人ぶつぶつと悩んでいたところで頂いた神の助言が表題である。

ControllerとViewは対応しなくてもいいんだよ!

まーじーかー!
ということで、GroupControllerへPOST、そこでPerson.newし、saveに失敗したらそのままformを再表示、成功したら取得したての:person_idを使って /:id/:person_id へとリダイレクトという流れに落ち着いた。

おしまい。