This one is a bit confusing.
I think the line that is problematic is in the controller and it's this line in particular:
recipe_tools = (recipe.recipe_tools + RecipeTool.generic)
My models:
class Recipe < ActiveRecord::Base
...
has_many :recipe_tools, dependent: :destroy
...
end
class RecipeTool < ActiveRecord::Base
belongs_to :story
end
class Story < ActiveRecord::Base
...
has_many :recipe_tools, dependent: :destroy
..
end
This is my controller:
module Api
module Recipes
class RecipeToolsController < Api::BaseController
before_filter :set_cache_buster
def index
# expires_in 30.minutes, public: true
recipe = Recipe.find(params[:recipe_id])
recipe_tools = (recipe.recipe_tools + RecipeTool.generic)
binding.pry
render json: recipe_tools, each_serializer: Api::V20150315::RecipeToolSerializer
end
end
end
end
This is my serializer:
module Api
module V20150315
class RecipeToolSerializer < ActiveModel::Serializer
cached
delegate :cache_key, to: :object
attributes :id,
:display_name,
:images,
:display_price,
:description,
:main_image,
:subtitle
def display_name
object.display_name
end
def images
object.story.get_spree_product.master.images
end
def display_price
object.story.get_spree_product.master.display_price
end
def description
object.story.description
end
def main_image
object.story.main_image
end
def subtitle
object.story.get_spree_product.subtitle
end
def spree_product
binding.pry
spree_product.nil? ? nil : spree_product.to_hash
end
private
def recipe_tool_spree_product
@spree_product ||= object.story.get_spree_product
end
end
end
end
This is my RecipeTool model:
class RecipeTool < ActiveRecord::Base
...
scope :generic, -> { where(generic: true) }
end
In the controller, we call recipe.recipe_tool only once and so I don't think we need to includes recipe_tool. We're not iterating through a collection of recipes and calling recipe_tool on each one so no N+1 problem.
However, we are creating a collection of recipe_tools in the controller by concatenating two collections of recipe_tools together. Recipe.generic is also a SQL query that generates generic recipe_tools.
I think the N+1 problem is happening in generating the JSON response via the serializer. We call recipe_tool.story a lot which would generate a SQL queries each time we call #story and we do that on a collection of recipe_tools.
Aucun commentaire:
Enregistrer un commentaire