Skip to content

Commit

Permalink
Use our optimized decorators to serialize pages
Browse files Browse the repository at this point in the history
BREAKING: This removes the all_elements relation from the includable
relationships and uses an eager loaded elements
collection that includes all publicly available elements from that page.

Use client side filtering and grouping to seperate fixed ones from
other elements and use a deserializer that supports
nesting.
  • Loading branch information
tvdeyen committed Jan 19, 2021
1 parent 0755ffe commit 743ff01
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
9 changes: 5 additions & 4 deletions app/controllers/alchemy/json_api/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true

module Alchemy
module JsonApi
class PagesController < JsonApi::BaseController
Expand Down Expand Up @@ -48,15 +49,15 @@ def page_scope
def page_scope_with_includes
base_page_scope.
with_language(Language.current).
preload(language: {nodes: [:parent, :page]}, all_elements: [:parent_element, :nested_elements, { contents: { essence: :ingredient_association } }])
preload(language: { nodes: [:parent, :page] }, elements: { contents: { essence: :ingredient_association } })
end

def base_page_scope
# cancancan is not able to merge our complex AR scopes for logged in users
if can?(:edit_content, Page)
Page.all
if can?(:edit_content, ::Alchemy::Page)
::Alchemy::JsonApi::Page.all
else
Page.published
::Alchemy::JsonApi::Page.published
end
end

Expand Down
14 changes: 7 additions & 7 deletions app/serializers/alchemy/json_api/page_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ class PageSerializer
)

belongs_to :language, record_type: :language, serializer: ::Alchemy::JsonApi::LanguageSerializer

has_many :elements, record_type: :element, serializer: ::Alchemy::JsonApi::ElementSerializer
has_many :fixed_elements, record_type: :element, serializer: ::Alchemy::JsonApi::ElementSerializer

has_many :all_elements, record_type: :element, serializer: ::Alchemy::JsonApi::ElementSerializer do |page|
page.all_elements.select { |e| e.public? && !e.trashed? }
end

with_options if: ->(_, params) { params[:admin] == true } do
attribute :tag_list
attribute :tag_list do |page|
Gutentag::Tagging.where(
taggable_id: page.id,
taggable_type: "Alchemy::Page",
).joins(:tag).pluck("gutentag_tags.name")
end

attribute :status
end
end
Expand Down
29 changes: 14 additions & 15 deletions spec/serializers/alchemy/json_api/page_serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "alchemy/test_support/factories"

RSpec.describe Alchemy::JsonApi::PageSerializer do
let(:page) do
let(:alchemy_page) do
FactoryBot.create(
:alchemy_page,
urlname: "a-page",
Expand All @@ -14,6 +14,7 @@
)
end
let(:options) { {} }
let(:page) { Alchemy::JsonApi::Page.find(alchemy_page.id) }

subject(:serializer) { described_class.new(page, options) }

Expand Down Expand Up @@ -52,22 +53,20 @@
end

describe "relationships" do
let(:element) { FactoryBot.create(:alchemy_element) }
let(:fixed_element) { FactoryBot.create(:alchemy_element, fixed: true) }
let(:trashed_element) { FactoryBot.create(:alchemy_element, :trashed) }
subject { serializer.serializable_hash[:data][:relationships] }
let!(:element) { FactoryBot.create(:alchemy_element, page: alchemy_page) }
let!(:fixed_element) { FactoryBot.create(:alchemy_element, page: alchemy_page, fixed: true) }
let!(:non_public_element) { FactoryBot.create(:alchemy_element, page: alchemy_page, public: false) }
let!(:trashed_element) { FactoryBot.create(:alchemy_element, page: alchemy_page).tap(&:trash!) }

before do
page.all_elements << element
page.all_elements << fixed_element
page.all_elements << trashed_element
trashed_element.trash!
end
subject { serializer.serializable_hash[:data][:relationships] }

it "has the right keys and values, and does not include trashed elements" do
expect(subject[:elements]).to eq(data: [{ id: element.id.to_s, type: :element }])
expect(subject[:fixed_elements]).to eq(data: [{ id: fixed_element.id.to_s, type: :element }])
expect(subject[:all_elements]).to eq(data: [{ id: element.id.to_s, type: :element }, { id: fixed_element.id.to_s, type: :element }])
it "has the right keys and values, and does not include trashed or hidden elements" do
expect(subject[:elements]).to eq(
data: [
{ id: element.id.to_s, type: :element },
{ id: fixed_element.id.to_s, type: :element },
],
)
expect(subject[:language]).to eq(data: { id: page.language_id.to_s, type: :language })
end
end
Expand Down

0 comments on commit 743ff01

Please sign in to comment.