Rails 3 ActiveRecord .. как объединить или включить таблицы и получить сумму - PullRequest
1 голос
/ 02 января 2012

Вот соответствующая структура данных и ассоциации:

User (has_many completions)
- id

Quest (has_many completions)
- id
- points [amount that earned if completed]

Completions (belongs_to users and quests)
- user_id
- quest_id

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

Пример:

 Quests
  id 1
  points 25
  --
  id 2
  points 10
  --
  id 3
  points 50

 Completions
  user_id 1
  quest_id 1
  --
  user_id 1
  quest_id 2
  --
  user_id 2
  quest_id 3

В этом примере user_id 1 набрал 35 баллов (25 + 10), а user_id 2 набрал 50 баллов.

Итак, два вопроса:

1) Как мне написать запросв Rails, чтобы я мог перечислить всех пользователей и их общее количество очков?

2) Это лучший способ справиться с этим типом функциональности?

Спасибо!

1 Ответ

1 голос
/ 02 января 2012

Довольно просто сделать с быстрым reduce и запросом.

class User < ActiveRecord::Base
  has_many :completions
  has_many :quests, :through => :completions

  attr_accessor :total_points

  # calculates points for individual user
  def points
    @total_points ||= quests.reduce(0) { |sum, quest| sum + quest.points }
    # note this doesn't reload, so if you add a completion without reloading the
    # user object this will be stale
  end

  # when getting a list of users, make sure you use an efficient query to
  # fetch all of the associated quests
  # 
  # this is the same as using `scope :with_quests, include(:quests)`
  def self.with_quests
    include(:quests)
  end
end

# outside of your model:
@users = User.with_quests.all

# and in a view (e.g. _user.html.erb):
Points: <%= user.points %>

Ура!

...