2013-10-15 3 views
1

Мои модели являются:Наиболее эффективные рельсы присоединиться вызов для этого случая

class Link < ActiveRecord::Base 
    has_many :votes 
    belongs_to :user 
end 

class Vote < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :link 
end 

class User < ActiveRecord::Base 

    has_secure_password 

    has_many :links 
    has_many :votes 
end 

У меня есть страница, где я список всех ссылок в системе. Для каждой ссылки я хочу отобразить как текущую сумму всех голосов, так и вопрос о том, проголосовал ли пользователь за запрос по этой конкретной ссылке (и если да, то какая была ценность этого голоса). Я хочу сделать это наиболее эффективным образом.

В настоящее время для того, чтобы вернуть ссылки и сумму голосов у меня есть это в моем контроллере Ссылки:

def index 
    @links = Link.all(:joins => :votes, :select => "links.*, sum(votes.value) as votes_total", :group => "links.id") 
end 

, который работает хорошо и дает мне всю информацию в одном вызове. Поэтому мой вопрос: мне нужно сделать второй запрос, чтобы вернуть голосование (если оно существует) для current_user или я могу каким-то образом включить это в свой первый запрос?

Кроме того, возможно, мне нужно создать какой-то sum_caching в базе данных, но я не уверен, что это лучший способ. Есть предположения?

ответ

0

Вы могли бы сделать что-то вроде этого:

@links = Link. 
    joins(:votes). 
    select(
    "links.*, sum(votes.value) as votes_total, sum(case votes.user_id when #{current_user.id} then votes.value else 0 end) as current_vote", 
    :group => "links.id" 
) 

Это даст вам значение голосов текущего пользователя, как @links.first.current_vote. Конечно, если ваша система имеет голоса с нулевым значением, она не различает «текущий пользователь, проголосовавший 0 по этой ссылке», и «текущий пользователь не голосовал по этой ссылке». Вы можете добавить еще одно выбранное значение (sum(case votes.user_id when #{current_user.id} then 1 else 0 end) as current_vote_exists), чтобы обработать это, я полагаю.

Естественно, вы хотите быть очень осторожным при интерполяции в SQL, подобном этому, и/или искать инструменты для очистки SQL, которые поставляются с ActiveRecord.

Смежные вопросы