0

次のように、Post モデルと View モデル (ユーザーによる各投稿のビューを記録します) があります。

class View < ActiveRecord::Base
    belongs_to :user, :class_name => 'User'
    belongs_to :post, :class_name => 'Post'
    validates_uniqueness_of :user_id, :scope =>:post_id
end

各投稿には、「special」という名前のブール フィールドがあります。

次の並べ替え条件ですべての投稿を取得したい:

  1. 投稿が「特別」であり、現在のユーザー (user_id=2 など) によって閲覧されていない場合、それは結果の一番上に表示され、id によって内部的に降順で並べ替えられます)。
  2. 投稿の id フィールドに基づいて、他のすべての投稿 (特別および閲覧特別ではない) を並べ替えます。

私がそれを行うことができるかどうか、またどのようにできるかわかりません。

まず、次のクエリを試しました。

posts = Post.order("(case when special = true then 'special desc, id desc' else 'id desc' end)")

しかし、それはおかしな動作をします: すべての特別な投稿を一番上に返し、その後に通常の投稿が続きますが、ID は昇順でソートされます。

ここで何が欠けていますか?また、このような複雑な order by 句で join (ビュー テーブル用) を使用するにはどうすればよいですか? このための SQL を書き込もうとしましたが、そこでも苦労しました。光を見せてください:)

PS私はRailsが初めてで、まだ学んでいます。

4

1 に答える 1

2

あなたが投稿したコードは、行ごとに2つの文字列リテラルの1つを計算し、それに基づいて順序付けするため、必要な例が得られません。私は次のようなことをします

Post.order('special desc, id desc')

Rails はブール値フィールドを MySQL に 0/1 として保存するため、特別な投稿が非特別な投稿より前にソートされます。

これにビューを追加しても、大きな変化はありません: ビュー テーブルに参加したままにして、次のようにする必要があります。

Post.joins('left join views on posts.id=post_id and user_id=2').order(' ( views.id is null && special)  desc, id desc')

is null、ビューが見つかったかどうかを検出し、投稿の特殊性で AND 処理されます。

于 2012-07-21T23:22:10.277 に答える