2016-05-06 2 views
0

と私のコントローラでRailsのActiveRecordのは...私はいくつかのモデルを持っている実行時パラメータ

class Game < ActiveRecord::Base 
    belongs_to :manager, class_name: 'User' 
    has_many :votes 
end 

class Vote < ActiveRecord::Base 
    belongs_to :game 
    belongs_to :voter, class_name: 'User' 
end 

class User < ActiveRecord::Base 
    has_many :games, dependent: :destroy 
    has_many :votes, dependent: :destroy 
end 

を含んで、私は次のコードを持っている...

user = User.find(params[:userId]) 
games = Game.includes(:manager, :votes) 

私は追加したいと思います属性/メソッドvoted_on_by_userはuser_idパラメータを受け取り、true/falseを返します。私は一般的にRailsとRubyに比較的新しいので、これを達成するためのきれいな方法を考え出すことができませんでした。理想的には私は...ちょうど私のゲームのモデルにこのような何かを追加するので

def voted_on_by_user(user) 
    votes.where(voter: user).exists? 
end 

N+1 queries problemを避けたいのですが、私はただでそれを行う方法を把握するためのRuby/Railsのに十分精通していませんよ1回のデータベースラウンドトリップ。助言がありますか?調査

私が試したいくつかのものは/

  • Specifying conditions on Eager Loaded Associations

    • 私はこれを指定したり、voted_on_by_userのような別の名前が含まれて与えるするかどうかはわかりません。これは...

    Game.includes(:manager, :votes).includes(:votes).where(votes: {voter: user})

  • Getting clever with joins私が欲しいものを私に与えるものではありません。そのため、おそらく何かのような...

    Game.includes(:manager, :votes).joins("as voted_on_by_user LEFT OUTER JOIN votes ON votes.voter_id = #{userId}")

答えて

1

すでにincludevotesをINGのしているので、あなただけの非DB操作を使用してvotesを数えることができます:votesがプリロードされている場合game.votes.select{|vote| vote.user_id == user_id}.present?は、追加のクエリを実行しません。

あなたは、必ずしもクエリでフィールドを配置したい場合、あなたは(あなたがgame_idを省略しても加入から)LEFT JOINと2番目の考えに非常に似て静脈内GROUP BYをしようとするかもしれません:

Game.includes(:manager, :votes).joins("LEFT OUTER JOIN votes ON votes.voter_id = #{userId} AND votes.game_id = games.id").group("games.id").select("games.*, count(votes.id) > 0 as voted_on_by_user") 
+0

ニース!その最初の提案は魅力のように機能します。私はゲームにループを追加し、attr_accessorをモデルに追加しました。しかし、2番目の提案はエラーを投げていた。 Mysql2 ::エラー:...右の構文について近くに使用するための「*)> 0 はまた、私は、コードのマルチラインを作るためにあなたの答えを編集してみましたが、編集はでなければならないので、SO私にはできないだろう少なくとも6文字。あなたがそれを行うことができれば、将来の訪問者のために物事をより明確にするかもしれない:) – Southerneer

+0

申し訳ありません、ただ編集しました。実際の列を数える必要があるので、 'count(votes。*)'は 'count(votes.id)'だったはずです。 –

+0

あなたは人間です! – Southerneer

関連する問題