加入 current_user 对每首歌曲的评分
Join current_user's rate to each song
我需要在索引中显示当前用户对歌曲的评分。
我有关联的模型:
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy
def user_rate(user)
votes.find_by(user_id: user).try(:rate)
end
end
class Vote < ActiveRecord::Base
belongs_to :song, counter_cache: true
belongs_to :user
end
票 table:
create_table "votes", force: :cascade do |t|
t.integer "rate"
t.integer "user_id"
t.integer "song_id
end
以及 SongsController 中的索引操作:
def index
respond_with @songs = Song.includes(:votes).all
end
在songs/index.json.rabl我找当前用户投票(每个用户只能投票一次)
collection @songs
extends "songs/base"
attributes :thumb_cover
node(:current_user_rate){ |song| song.user_rate(current_user) }
但是 song.user_rate(current_user)
生成 n+1 查询 :(
User Load (0.9ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
Song Load (0.6ms) SELECT "songs".* FROM "songs"
Vote Load (0.8ms) SELECT "votes".* FROM "votes" WHERE "votes"."song_id" = ? AND "votes"."user_id" = 1 LIMIT 1 [["song_id", 1]]
Vote Load (0.3ms) SELECT "votes".* FROM "votes" WHERE "votes"."song_id" = ? AND "votes"."user_id" = 1 LIMIT 1 [["song_id", 2]]
有没有一种方法可以在一次查询中将当前用户的 vote.rate 列加入每首歌曲?
更改为;
def self.user_rate(user)
self.votes.find_by(user_id: user.id).try(:rate)
end
你最好潜入 ActiveRecord Association Extensions
:
#app/models/song.rb
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy do
def user_rate(user)
find_by(user_id: user.id).try(:rate)
end
end
end
这将允许:
@song = Song.find params[:id]
@rating = @song.votes.user_rate current_user #-> 5 or false
如果您不想执行另一个查询,您可以尝试使用可通过扩展程序访问的 proxy_association
对象:
#app/models/song.rb
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy do
def user_rate(user)
ratings = proxy_association.target.map {|f| [f.user_id, f.rate]}
rating = ratings.select { |user_id, rate| user_id == user.id }
rating.first[1] if rating.first
end
end
end
您将能够使用:
@song = Song.find params[:id]
@rating = @song.votes.try(:by, current_user) #-> 5 or false
if @rating
...
end
未经测试,但我以前以类似的方式使用过 proxy_association
。
我需要在索引中显示当前用户对歌曲的评分。
我有关联的模型:
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy
def user_rate(user)
votes.find_by(user_id: user).try(:rate)
end
end
class Vote < ActiveRecord::Base
belongs_to :song, counter_cache: true
belongs_to :user
end
票 table:
create_table "votes", force: :cascade do |t|
t.integer "rate"
t.integer "user_id"
t.integer "song_id
end
以及 SongsController 中的索引操作:
def index
respond_with @songs = Song.includes(:votes).all
end
在songs/index.json.rabl我找当前用户投票(每个用户只能投票一次)
collection @songs
extends "songs/base"
attributes :thumb_cover
node(:current_user_rate){ |song| song.user_rate(current_user) }
但是 song.user_rate(current_user)
生成 n+1 查询 :(
User Load (0.9ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
Song Load (0.6ms) SELECT "songs".* FROM "songs"
Vote Load (0.8ms) SELECT "votes".* FROM "votes" WHERE "votes"."song_id" = ? AND "votes"."user_id" = 1 LIMIT 1 [["song_id", 1]]
Vote Load (0.3ms) SELECT "votes".* FROM "votes" WHERE "votes"."song_id" = ? AND "votes"."user_id" = 1 LIMIT 1 [["song_id", 2]]
有没有一种方法可以在一次查询中将当前用户的 vote.rate 列加入每首歌曲?
更改为;
def self.user_rate(user)
self.votes.find_by(user_id: user.id).try(:rate)
end
你最好潜入 ActiveRecord Association Extensions
:
#app/models/song.rb
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy do
def user_rate(user)
find_by(user_id: user.id).try(:rate)
end
end
end
这将允许:
@song = Song.find params[:id]
@rating = @song.votes.user_rate current_user #-> 5 or false
如果您不想执行另一个查询,您可以尝试使用可通过扩展程序访问的 proxy_association
对象:
#app/models/song.rb
class Song < ActiveRecord::Base
has_many :votes, dependent: :destroy do
def user_rate(user)
ratings = proxy_association.target.map {|f| [f.user_id, f.rate]}
rating = ratings.select { |user_id, rate| user_id == user.id }
rating.first[1] if rating.first
end
end
end
您将能够使用:
@song = Song.find params[:id]
@rating = @song.votes.try(:by, current_user) #-> 5 or false
if @rating
...
end
未经测试,但我以前以类似的方式使用过 proxy_association
。