====== recently_commented_onが正しく機能しない ======
[[http://www.postgresql.jp|PostgreSQL]]をバックエンドにして、「最近のコメント」を作成しようとすると、おかしなエントリが表示されてしまいます。([[http://www.mysql.com/|MySQL]]の場合やSQLiteの場合はわかりません。ファイルをバックエンドにしている場合は大丈夫です。)
これは、**DISTINCT**の使い方が正しくないためです。大まかに言うと、MTはコメントの一覧を作成して、これを作成された日時で降順に(descend)ソートします。そしてその結果から、コメントされているエントリの一覧を作成します。このとき、ひとつのエントリに複数のコメントがあれば、当然、エントリが重複して抽出されますから、これを解消するために、**DISTINCT**を指定しています。ところが、**DISTINCT**は重複行は取り除くものの、**その結果得られるエントリ一覧の順序は保証されない**のです。従って、折角ソートして作った一覧を、**DISTINCT**が壊してしまっているのです。
とりあえず、以下のパッチをあてることで、この問題は解決します。但し、この修正を行なった後に、バックエンドを[[http://www.postgresql.jp|PostgreSQL]]以外に変更すると、おかしなことになりますので、その場合は lib/MT/Template/ContextHandlers.pm(MT-3.1xの場合はlib/MT/Template/Context.pm)をオリジナルのものに戻すようにしてください。なお、パッチはMT-3.2以降と、MT-3.1xとで微妙に違います。
余談ですが、「最近のコメント」を作るために、sort_order="ascend"を指定するようにかいてある記事を見かけますが、このオプションは recently_commented_onには無効ですし、更にいうと、昇順(ascend)にしたら、それは**最近の**ではなく**最古の**になってしまいますので、**あらゆる意味で間違いです**。
===== パッチ(MT-3.2) =====
[[http://www.wildtree.jp/~araki/archive/mtpgrc32.zip|パッチファイル]]
*** MT-3.2-b1-ja.orig/lib/MT/ObjectDriver/DBI/postgres.pm 2005-09-02 16:13:00.000000000 +0900
--- MT-3.2-b1-ja/lib/MT/ObjectDriver/DBI/postgres.pm 2005-09-13 17:14:18.000000000 +0900
***************
*** 86,91 ****
--- 86,106 ----
$sql = $s_sql . $sql;
$w_sql .= ") t\n";
}
+ elsif ($j_args->{'aggregate_sort'}) {
+ ## sorting with aggregate function,
+ my $as_args = $j_args->{'aggregate_sort'};
+ my $cols = $class->column_names;
+ my $s_sql = "from (select " .
+ join(', ', map "${tbl}_$_", @$cols) .
+ ", $as_args->{'function'}(${j_tbl}_$as_args->{'column'}) as ${tbl}_${j_tbl}_$as_args->{'column'}\n";
+ $sql = $s_sql . $sql;
+ $w_sql .= "group by " .
+ join(',', map "${tbl}_$_", @$cols) . "\n";
+ $w_sql .= ") t\n";
+ my $dir = $as_args->{'direction'} &&
+ $as_args->{'direction'} eq 'descend' ? 'desc' : 'asc';
+ $w_sql .= "order by ${tbl}_${j_tbl}_$as_args->{'column'} $dir\n";
+ }
if (my $n = $j_args->{limit}) {
$n =~ s/\D//g; ## Get rid of any non-numerics.
*** MT-3.2-b1-ja.orig/lib/MT/Template/ContextHandlers.pm 2005-09-02 16:13:00.000000000 +0900
--- MT-3.2-b1-ja/lib/MT/Template/ContextHandlers.pm 2005-09-13 17:17:15.000000000 +0900
***************
*** 866,875 ****
require MT::Comment;
$args{'join'} = [ 'MT::Comment', 'entry_id',
{ blog_id => $blog_id, visible => 1 },
! { 'sort' => 'created_on',
! direction => 'descend',
! unique => 1,
! limit => $n } ];
$no_resort = 1;
}
@entries = MT::Entry->load(\%terms, \%args);
--- 866,875 ----
require MT::Comment;
$args{'join'} = [ 'MT::Comment', 'entry_id',
{ blog_id => $blog_id, visible => 1 },
! { 'aggregate_sort' => { 'column' => 'created_on',
! 'function' => 'max',
! 'direction' => 'descend' },
! limit => $n } ];
$no_resort = 1;
}
@entries = MT::Entry->load(\%terms, \%args);
===== パッチ(MT-3.1x) =====
[[http://www.wildtree.jp/~araki/archive/mtpgrc.zip|パッチファイル]]
*** MT-3.121-full-ja.orig/lib/MT/ObjectDriver/DBI/postgres.pm 2004-10-01 15:18:37.000000000 +0900
--- MT-3.121-full-ja/lib/MT/ObjectDriver/DBI/postgres.pm 2005-01-18 09:54:25.000000000 +0900
***************
*** 78,83 ****
--- 78,98 ----
$sql = $s_sql . $sql;
$w_sql .= ") t\n";
}
+ elsif ($j_args->{'aggregate_sort'}) {
+ ## sorting with aggregate function,
+ my $as_args = $j_args->{'aggregate_sort'};
+ my $cols = $class->column_names;
+ my $s_sql = "from (select " .
+ join(', ', map "${tbl}_$_", @$cols) .
+ ", $as_args->{'function'}(${j_tbl}_$as_args->{'column'}) as ${tbl}_${j_tbl}_$as_args->{'column'}\n";
+ $sql = $s_sql . $sql;
+ $w_sql .= "group by " .
+ join(',', map "${tbl}_$_", @$cols) . "\n";
+ $w_sql .= ") t\n";
+ my $dir = $as_args->{'direction'} &&
+ $as_args->{'direction'} eq 'descend' ? 'desc' : 'asc';
+ $w_sql .= "order by ${tbl}_${j_tbl}_$as_args->{'column'} $dir\n";
+ }
if (my $n = $j_args->{limit}) {
$n =~ s/\D//g; ## Get rid of any non-numerics.
*** MT-3.121-full-ja.orig/lib/MT/Template/Context.pm 2004-10-26 17:27:53.000000000 +0900
--- MT-3.121-full-ja/lib/MT/Template/Context.pm 2005-01-18 09:52:01.000000000 +0900
***************
*** 741,749 ****
} elsif (my $n = $args->{recently_commented_on}) {
$args{'join'} = [ 'MT::Comment', 'entry_id',
{ blog_id => $blog_id, visible => 1 },
! { 'sort' => 'created_on',
! direction => 'descend',
! unique => 1,
limit => $n } ];
$no_resort = 1;
}
--- 741,749 ----
} elsif (my $n = $args->{recently_commented_on}) {
$args{'join'} = [ 'MT::Comment', 'entry_id',
{ blog_id => $blog_id, visible => 1 },
! { 'aggregate_sort' => { 'column' => 'created_on',
! 'function' => 'max',
! 'direction' => 'descend' },
limit => $n } ];
$no_resort = 1;
}
[[MovableTypeに関して]]へ戻る。