spree-contrib / spree_multi_vendor

Spree marketplace extension. Create your own marketplace on top of Spree Commerce
https://spreecommerce.org/marketplace-ecommerce/
BSD 3-Clause "New" or "Revised" License
142 stars 135 forks source link

Error when creating an order - Wrong number of arguments (given 0, expected 1) #212

Open jeffAwesome opened 2 years ago

jeffAwesome commented 2 years ago
Screen Shot 2021-12-26 at 2 38 04 PM

This seems to be related to the order decorator in the spree multi-vendor gem.

I'm currently using the 4.4.0.rc1 of spree. Any advice would be greatly appreciated.

jeffAwesome commented 2 years ago

To add some additional notes

This happens as soon as I click new order in the admin dashboard... The add new order works fine until I add the multi vendor gem and run the migrations.

I've tested this multiple times with the same results each time the multi vendor gem is setup.

ronzalo commented 2 years ago

hi @jeffAwesome

I had the same problem with Spree 4.4.0.rc1 and the solution is to override the Spree::Api::V2::ResourceSerializerConcern so that it only includes getter methods that do not require parameters in their call

The issue start with this PR and this method because spree_multivendor define a bunch of `display` methods that are returned as instance getter methods with a required vendor argument

The patch is to remove these display_vendor_* methods from default attributes in the OrderSerializer

TL;DR

Create a ruby file with this

# app/serializers/concerns/spree/api/v2/resource_serializer_concern.rb
module Spree
  module Api
    module V2
      module ResourceSerializerConcern
        extend ActiveSupport::Concern

        def self.included(base)
          serializer_base_name = base.to_s.sub(/^Spree::Api::V2::Platform::/, '').sub(/Serializer$/, '')
          model_klazz = "Spree::#{serializer_base_name}".constantize

          base.set_type model_klazz.json_api_type
          # include standard attributes
          base.attributes(*model_klazz.json_api_columns)
          # include money attributes
          display_getter_methods(model_klazz).each do |method_name|
            base.attribute(method_name) do |object|
              object.public_send(method_name).to_s
            end
          end
        end

        # Notice the arity filter
        def self.display_getter_methods(model_klazz)
          model_klazz.new.methods.find_all do |method_name|
            next if model_klazz.new.method(method_name).arity.positive?
            next unless method_name.to_s.start_with?('display_')
            next if method_name.to_s.end_with?('=')
            next if [Spree::Product, Spree::Variant].include?(model_klazz) && method_name == :display_amount

            method_name
          end
        end
      end
    end
  end
end