0

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 の行の説明:

  1. Railscast から採用され、投票オプションを非表示にしません
  2. 明らかに効率的ですが、同じ問題が発生します
  3. 残りのコードが機能することを証明します。このオプションを実行すると、すべてのリンクが非表示になります
  4. 次の 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コードでこれを修正するにはどうすればよいですか?

4

1 に答える 1

1

間違っているのは SQL であるため、モデルにすべての正しい関連付けがあることを再確認してください。Userhas_many :micropostsを確認し、Micropost が次のようになっていることを確認します。

class Micropost < ActiveRecord::Base
  belongs_to :user

  has_reputation :votes, source: :user, aggregated_by: :sum
end

また、データベースを移行したことと、それらの関連付けに必要な正しい列がすべて含まれていることを再確認してください。

于 2013-02-27T13:53:50.457 に答える