количество «многие ко многим»

#ruby-on-rails #ruby-on-rails-3 #activerecord

#ruby-on-rails #ruby-on-rails-3 #activerecord

Вопрос:

 User.rb
has_many :votes
has_many :photos


Photo.rb
has_many :votes
belongs_to :user

Vote.rb
belongs_to :user
belongs_to :photo
  

Я хочу перечислить пользователей, проголосовавших за фотографию. Но этот список должен содержать информацию о том, сколько раз пользователь проголосовал за фотографию. Например, когда я захожу по url photos / 5 / statistics, там должен быть список, подобный приведенному ниже:

 1) User1   voted 30 times
2) User432 voted 15 times
3) User43  voted 12 times
  

Любая помощь будет оценена.

Комментарии:

1. чтобы получить запрошенный список, вы ничего не указываете о том, за какие фотографии было проголосовано, поэтому для первого пользовательского примера это было бы просто User.find(1).votes.count #=> 30

2. Мне не нужны все голоса пользователя, только голоса, которые он использовал для конкретной фотографии

Ответ №1:

Одним из способов сделать это было бы использование group_by

Например:

 Photo.first.votes.group_by(amp;:user).each do |user, votes| 
  puts "User #{user.id} voted #{votes.count} times"
end
  

Комментарии:

1. Хотя это работает хорошо, оно выполняет запрос в таблице users для каждого голосования. Учтите это, если производительность является проблемой для вас.

Ответ №2:

Итак, по сути, вы работаете изнутри модели Photo:

 class Photo < ActiveRecord::Base
  ...
  def voting_list
    votes.joins(:user).group(:user).count
  end
  ...
  

Это даст вам упорядоченный хэш, подобный следующему:

 {<user_object_1> => 14, <user_object_2> => 33, ...}
  

Ответ №3:

если вы хотите узнать, сколько раз один пользователь проголосовал за определенную фотографию, вы могли бы сделать что-то вроде:

 user = User.find_by_some_option
photo = user.photos.first
photo.votes.find{|vote| vote.user == user}.count