ruby-on-railspreloadpresenter

Combining Presenters and #includes in Rails query


Suppose I have the following setup in my Rails4 app:

A Student has_many degrees, a Degree belongs_to a Student. I have a StudentPresenter and a DegreePresenter corresponding to both models as well. (Presenters as defined here)

I want to query the following:

student_ids = [1,2,3,4]
students = Student.where(id: student_ids).includes(:degrees)

But I want to have access to the Presenter methods for both Student and Degree.

How do I preload data with Presenters?

Rails 4.1.5


Solution

  • The presenters in the blog post you linked to are just simple ruby objects that take a model as one of the arguments when creating a new presenter:

    So to create the StudentPresenters:

    students = Student.where(id: student_ids).includes(:degrees)
    decorated_students = students.map { |s| StudentPresenter.new(s, view_context) }
    

    Then you could add a method to StudentPresenter which returns decorated degrees;

    class StudentPresenter < BasePresenter
      def degrees
        @model.degrees.map { |d| DegreePresenter.new(d, @view) } 
      end
    end
    

    Added

    How this works with preloading? Since you are using includes

    With includes, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.

    Rails should load both students table and degrees as soon as you do students.map.