Skip to content

Override for relationship with super is not working. Also setter for a relationship is working anomalously #405

Open
@isfando

Description

@isfando
class BillingAccount < JsonApiClient::Resource

#internal class starts
  class Create < JsonApiClient::Resource

    property :billing_account_type, type: :string
    has_many :products, class_name: 'foo'

    def product_offerings=(items)
      #item._model is of type 'foo'
      self.products = items.map { |item| item._model }
    end

    def attributes_for_serialization
      relationship_keys = self.class.associations.collect(&:attr_name).map(&:to_s)
      super.reject { |k, v| v.nil? || relationship_keys.include?(k) }
    end

    def self.key_formatter
      JsonApiClient::UnderscoredKeyFormatter
    end

    def self.path(*)
      Bssapi::V1::BillingAccount.path
    end

    def meta
      {
        channel: 'abc'
      }
    end


    def as_json_api
      super.tap do |data|
        data['type'] = BillingAccount.type.dasherize
      end
    end

    def save(sync: true)
      saved = super()
      if saved && async_response?(last_result_set) && sync
        when_async_request_done(last_result_set) do |request|
          if request.done?
            self.id = billing_account_id
            true
          elsif request.failed?
            errors.add(:base, request.reasons || "unknown error")
            false
          end
        end
      else
        saved
      end
    end
  end
# internal class ends here


  has_many :products, class_name: 'foo'
  has_one :billing_account_type, class_name: 'bar'

  def meta
    {
      channel: 'abc'
    }
  end

  def product_offerings=(items)
    #item._model is of type 'foo'
    self.products = items.map { |item| item._model } 
  end

  def valid?
    if new_record?
      create = resource_for_create
      if create.valid?
        true
      else
        errors.merge!(create.errors)
        false
      end
    else
      super
    end
  end

  def save(sync: true)
    if new_record?
      create = resource_for_create
      if create.save(sync: sync)
        self.id = create.id
        true
      else
        errors.merge!(create.errors)
        false
      end
    else
      super()
    end
  end

  private

  def resource_for_create
    Create.new(
      attributes.merge(
        billing_account_type: billing_account_type # This is a relationship in GET and string in POST
      )
    )
  end
end

###########################################################################################################################
###########################################################################################################################
Reason for internal class:
Use a different class for POST to avail asynchronus creation etc.

Problem during Creation of new resource:
BillingAccount.new(
billing_account_type: "test",
product_offerings: items,
).save

The products relation will be absent from resulting pay load to api.

POST http://localhost:7777/api/v1/billing-accounts with body 
'{"data":{"type":"billing-accounts","attributes":{"billing_account_type":"1111"}},"meta":{"channel":"abc"}}'

If i remove the method #product_offerings= from the outer class (BillingAccount) then it works fine

POST http://localhost:7777/api/v1/billing-accounts with body 
'{"data":{"type":"billing-accounts","relationships":{"products":{"data":[{"type":"foo","id":"33333"}]}},"attributes":{"billing_account_type":"6002"}},"meta":{"channel":"abc"}}'

The method in the outer class BillingAccount is required for PATCH as BillingAccount::Create is only used for POST.
What can i do in such situation.

I have also used the following method to override the products relationship in BillingAccount::Create but it does not help either

class Create < JsonApiClient::Resource
  property :billing_account_type, type: :string
  has_many :products, class_name: 'foo'
  
  def products=(items)
    #item._model is of type 'foo'
    super(items.map { |item| item._model }) 
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions