2014-01-05 5 views
1

Каков наилучший способ показать пользователю свой тип голосования (за/против/воздержание) на странице с большим количеством сообщений?Лучший способ получить текущий тип голосования для сотен сообщений с Rails

прямой запрос

SELECT vote_type FROM votes WHERE post_id = 888 AND user_id = 888 

и прямой путь с рельсами

post.votes.where(:user_id => current_user.id).pluck(:vote_type).first 

но это слишком тяжело и глупо делать дб запрос для каждого поста.

Я могу построить массив posts_id и сделать один запрос

@posts.each do |post| 
    ids << post.id 
end 
votes = Vote.select(:post_id, :vote_type).where(:user_id => current_user.id, :post_id => ids) 
SELECT post_id, vote_type FROM votes WHERE user_id = 888 AND post_id IN (887, 888, 889) 

Есть ли встроенный в «Магическом» методы в рельсах? Я использую postgresql.

UPD +1 Способ же записи

current_user.votes.find_by_post_id(post.id) 

UPD2 Dummy-table on pastebin

+0

Похоже, что вы ищете нетерпеливой загрузки ассоциаций. Если вы могли бы опубликовать свои ассоциации моделей, а также действия вашего контроллера, можно было бы дать вам полный запрос. http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations – depa

+0

Да, это все. Совместимость моделей проста: Пользователь (has_many: сообщения, голоса), Post (принадлежит_to: user, has_many: votes), Голосовать (принадлежит_от: сообщение, пользователь). что лучше - 1000 частично кэшированных (?) небольших запросов или 1 большой запрос с IN (1..1000)? –

+0

@depa, что-то вроде этого? '@posts = Post.includes (: votes) .where (" vote.user_id "=> current_user.id)' Но это возвращает только сообщения с голосами и делает * страшный * SQL-запрос. –

ответ

0

Как о

votes = Post. 
    joins(:user). 
    joins("LEFT JOIN votes ON votes.post_id = posts.id AND votes.user_id = 1"). 
    select("posts.id, posts.title, users.id AS users_id, votes.vote_type") 

с

votes.map {|p| [p.id, p.title, p.users_id, p.vote_type] } 

я

[[1, "Say hello", 1, nil], [2, "Amazing world", 2, 1]] 
+0

Спасибо, старый путь обычно работает :) Я думаю, что нет встроенных методов (например, ассоциаций.), чтобы сделать это в рельсах? –

0
@posts = Post.all.includes(:votes).where(posts: { user_id: current_user.id }) 
+1

это получает все сообщения со ВСЕМИ ГОЛОСАМИ, а не только текущие голоса пользователей , Мне нужно что-то вроде этого (Post.all) + (включает (: votes) .where (: user_id => current_user.id)) ' –

+0

Я думаю, проблема в состоянии. Если вы используете только включает в себя - все сообщения будут загружаться, но если вы используете вложения с условиями, будут только сообщения, которые включают в себя голоса, которые соответствуют условиям –

+0

Право. Проверьте мой обновленный ответ. – depa

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

  • Нет связанных вопросов^_^