Hi all, I’m attempting to extend the Promotions A...
# support
w
Hi all, I’m attempting to extend the Promotions API routes to include an index route. So far, I’ve been able to return all Promotion objects but when I try to extend the object with an
includes
method to also return the PromotionAction, PromotionRule, and PromotionCode, the response is still the same. I’ve also added
[:rules, :codes, :actions]
to
Spree::Api::Config.promotion_attributes
. Am I missing anything? Here is my controller override module:
Copy code
module SolidusTestApp
  module Spree
    module Api
      module PromotionsControllerDecorator
        # override the existing before_action on the PromotionsController
        def self.prepended(base)
          base.before_action(
            :load_promotion,
            only: [:show],
          )
        end

        def index
          @promotions = promotion_scope.includes(promotion_includes).ransack(params[:q]).result
          @promotions = paginate(@promotions)
          respond_with(@promotions.to_json)
        end

        private

        def promotion_scope
          ::Spree::Promotion.accessible_by(current_ability)
        end


        def promotion_includes
          [:promotion_rules, :promotion_actions, :codes]
        end

        ::Spree::Api::PromotionsController.prepend self

      end
    end
  end
end

# Spree::Api::PromotionsController.prepend(DockerSample::Spree::Api::PromotionsControllerDecorator)
Here’s what I get from pinging
localhost:3000/api/promotions
Copy code
[
    {
        "id": 1,
        "description": "",
        "expires_at": null,
        "starts_at": "2022-12-20T00:00:00.000Z",
        "name": "First Subscription 30% Off",
        "usage_limit": null,
        "match_policy": "all",
        "advertise": false,
        "path": null,
        "created_at": "2022-12-16T20:34:09.680Z",
        "updated_at": "2022-12-20T21:05:39.423Z",
        "promotion_category_id": null,
        "per_code_usage_limit": null,
        "apply_automatically": false
    }
]
Here is what I expect
Copy code
[{
    "id": 1,
    "name": "First Subscription 30% Off",
    "description": "",
    "expires_at": null,
    "starts_at": "2022-12-20T00:00:00.000Z",
    "type": null,
    "usage_limit": null,
    "match_policy": "all",
    "advertise": false,
    "path": null,
    "rules": [
        {
            "id": 1,
            "promotion_id": 1,
            "product_group_id": null,
            "created_at": "2022-12-19T19:06:51.229Z",
            "updated_at": "2022-12-19T19:07:04.097Z",
            "code": null,
            "preferences": {
                "match_policy": "any"
            }
        }
    ],
    "codes": [
        {
            "id": 1,
            "promotion_id": 1,
            "value": "firstsub30",
            "created_at": "2022-12-16T20:34:09.687Z",
            "updated_at": "2022-12-16T20:34:09.687Z",
            "promotion_code_batch_id": null
        }
    ],
    "actions": [
        {
            "id": 1,
            "promotion_id": 1,
            "position": null,
            "deleted_at": null,
            "preferences": {},
            "created_at": "2022-12-19T19:07:12.884Z",
            "updated_at": "2022-12-19T19:07:12.884Z"
        }
    ]
}]
Any insight would be greatly appreciated!
n
.includes()
doesn't display the included models, it just loads them into memory so that you can run faster queries and avoid N+1 to get to what you are tring to do you should create a
.json.jbuilder
view file and write it there
w
That’s helpful, thank you! Why use jbuilder view instead of something like
to_json
? I found this snippet in the solidus_subscriptions source code:
Copy code
render json: subscription.to_json(include: [:line_items, :shipping_address, :billing_address])
And this approach actually worked for me though for some reason, I’m only getting 1 promotion object + associations when I expect 8.
n
didn't know about that option to answer your question: https://stackoverflow.com/questions/60428785/json-jbuilder-v-s-render-json-method