2016-04-16 6 views
0

Ich habe 2 Modelle in meiner App: Person und Review Jede Person hat viele Bewertungen und jede Bewertung gehört zu einer Person. Ich habe ein Attribut grade Innenseite meines Review-Modell genannt, und ich mag den durchschnittlichen Grad von jeder Person angezeigt werden, damit ich diesen Bereich geschrieben:So greifen Sie auf eine Eigenschaft von gehören_Modell aus einem Bereich

scope :average_grade, -> { self.first.review.average(:grade) } 

Gibt es eine bessere Art und Weise, dass zu tun? Neben den 2-Abfragen, dass diese Methode braucht, muß ich auch noch 2 Abfragen ausführen, um das richtige Person Objekt in meinem Controller zu bekommen:

def show 
    @average = Person.includes(:review).where(id: params[:id]).average_grade 
    @person = Person.includes(:review).find(params[:id]) 
end 

Wie kann ich alle diese Abfragen zu vermeiden?

Antwort

2

Ihr Bereich ist eine Instanzmethode und nicht der Bereich, da ActiveRecord :: Relation nicht zurückgegeben wird.

Ich schlage vor, Sie folgendes zu tun:

# person.rb: 
def average_grade 
    review.average(:grade) 
end 

# controller: 
def show 
    @person = Person.find(params[:id]) 
    @average = @person.average_grade 
end 
+0

Danke Durch die Art und Weise finden, warum das Verfahren nicht selbst braucht!? – Bezzi

+1

cause 'self' Inside-Instanz-Methode kann weggelassen werden, wenn die Methode Instanz aufruft. – Ilya

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 

Mehr zu Moderatoren könnten Sie hier Railscasts PRO #287 Presenters from Scratch