2013-08-20 5 views
0

Предположим, у меня две модели: пользователь и точка.Самостоятельная ссылка в модели Rails

Точка принадлежит пользователю. Точка имеет «сумму». Я хочу определить метод в модели Point, который будет возвращать общие точки пользователя. Я бы назвал это так: user.points.total

Я просто не знаю, как определить метод в модели Point таким образом, что мне не нужно передавать ему идентификатор пользователя. Я бы предположил, что есть простой способ сделать это, но мой Googlefu терпит неудачу.

ответ

3

Предполагая, что модель пользователя имеет

has_many :points 

вы можете сделать, как это в модели пользователя

def total_points 
    points.sum(:amount) 
end 
+0

Это был мой первый инстинкт, но я предпочел бы ссылаться на него как 'User.points.total' вместо' User.total'. Спасибо хоть! – opticon

+0

@TheSciz Я не вижу ничего неправильного в 'user.total_points', но вы можете выполнить то, что хотите, с помощью [Расширение ассоциации] (http://guides.rubyonrails.org/association_basics.html#association-extensions) – rubish

0

Учитывая, что вы хотите метод, описанный в Point модели, вы хотели бы использовать:

class Point 
    def total 
    user.points.sum(:amount) 
    end 
end 

Тогда вы можете получить общие очки для пользователя, связанные с ag iven point путем вызова point.total. Вы не можете получить общие баллы через User.points.total, потому что User - это класс и не относится к определенному пользователю.

+0

Спасибо @Peter. Используя этот метод, я получаю следующую ошибку, пытающуюся вызвать ее, используя anyuser.points.total: 'undefined method' total 'for []: ActiveRecord :: Relation'. Любая идея, почему это было бы? – opticon

+0

Можете ли вы поделиться кодом, который вызывает ошибку? –

+0

Извините, я не читал ваш комментарий. Поскольку вы попросили метод в 'Point', вам нужно вызвать его через экземпляр« Point ». –

0

Рассмотрите возможность использования #sum, который использует сумму SQL для агрегации.

Например,

person.points.sum('amount') 

или

# inside User.rb 
def total 
    points.sum('amount') 
end 
Смежные вопросы