我的应用程序中有2个模型:人物和评论每个人都有很多评论,每个评论都属于一个人。我的评论模型中有一个名为grade
的属性,我想显示每个人的平均成绩,所以我写了这个范围:
scope :average_grade, -> { self.first.review.average(:grade) }
有没有更好的方法呢?除了这个方法需要的2个查询之外,我还必须运行另外2个查询以在我的控制器中获取正确的Person对象:
def show
@average = Person.includes(:review).where(id: params[:id]).average_grade
@person = Person.includes(:review).find(params[:id])
end
我怎么能避免所有这些疑问?
答案 0 :(得分:2)
您的范围是实例方法而不是范围,因为它不返回ActiveRecord :: Relation对象。
我建议你这样做:
# person.rb:
def average_grade
review.average(:grade)
end
# controller:
def show
@person = Person.find(params[:id])
@average = @person.average_grade
end
答案 1 :(得分:1)
# person.rb
class Person < ActiveRecord::Base
has_many :reviews
end
# review.rb
class Review < ActiveRecord::Base
belongs_to :person
scope :by_person, ->(person) { where(person_id: person) }
end
# persons_controller
class PersonsController < ApplicationController
helper_method :person
private
def person
return @person if defined? @person
@person = Person.find(params[:id])
end
end
# show.html.haml
- present(person) do |person_presenter|
%p= person_presenter.average_grade
# person_presenter.rb
class PersonPresenter < BasePresenter
present :person
def average_grade
Review.by_person(person).average(:grade)
end
end
有关演示者的更多信息,请访问Railscasts PRO #287 Presenters from Scratch