Railscast 364で説明されている Active Record Reputation System を実装しています。
投票や集計 (ユーザーごと、投稿ごと) など、ほとんどの作業が完了しました。
ユーザーがすでに投票しているときに投票オプションを非表示にしようとすると問題が発生します。Railscast は関数voted_for?
を使用してこの非表示を行います。私は答えを探しましたが、他の誰もこの問題を抱えていないか (可能性は低い)、彼らの問題を私のものに戻すことができません (可能性があります)。
個別に実行する 4 行の私の適応コードは、次のようになります。
# snippet of User.rb:
has_many :evaluations, class_name: "RSEvaluation", as: :source
has_reputation :votes, source: {reputation: :votes, of: :microposts}, aggregated_by: :sum
def voted_for?(micropost)
evaluations.where(target_type: micropost.class, target_id: micropost.id).present? #1.
evaluations.exists?(target_type: micropost.class, target_id: micropost.id) #2.
true #3.
evaluations.exists?(target_type: "Micropost", target_id: 1) #4.
end
1 ~ 4 の行の説明:
- Railscast から採用され、投票オプションを非表示にしません
- 明らかに効率的ですが、同じ問題が発生します
- 残りのコードが機能することを証明します。このオプションを実行すると、すべてのリンクが非表示になります
次の SQL が生成されます ( から取得
development.log
):SELECT COUNT(*) FROM "rs_evaluations" WHERE "rs_evaluations"."target_id" = 1 # this should be "source_id" AND "rs_evaluations"."target_type" = 'User' # this should be "source_type" AND "rs_evaluations"."target_type" = 'Micropost' # correct AND "rs_evaluations"."target_id" = 302 # correct
だから私は問題を見つけました。正しい列名で SQL を実行すると、期待どおりに動作します。
Railsコードでこれを修正するにはどうすればよいですか?