0

每當我想創建一個新項目時,我的API中有不匹配類型的問題。如何使用jsonapi資源修復API,這些資源使用不匹配類型進行響應並且不允許我創建記錄?

它發生在兩個地方:

  1. 當我嘗試發佈一個新的項目

POST http://localhost:8060/datasets/

{ 
    "data": { 
      "type": "datasets", 
      "attributes": { 
       "doi": "10.5259/2008120816KAKA", 
       "version": 0, 
       "is-active": "1", 
       "datacentre": 201 
      } 
    } 

響應

"errors": [ 
    { 
     "title": "Internal Server Error", 
     "detail": "Internal Server Error", 
     "code": "500", 
     "status": "500", 
     "meta": { 
      "exception": "Datacentre(#23863440) expected, got 201 which is an instance of Fixnum(#4211740)", 
      "backtrace": [ 
       "/usr/local/rvm/gems/ruby-2.3.3/gems/activerecord-5.1.1/lib/active_record/associations/association.rb:239:in `raise_on_type_mismatch!'", 
       "/usr/local/rvm/gems/ruby-2.3.3/gems/activerecord-5.1.1/lib/active_record/associations/belongs_to_association.rb:11:in `replace'", 
       "/usr/local/rvm/gems/ruby-2.3.3/gems/activerecord-5.1.1/lib/active_record/associations/singular_association.rb:15:in `writer'", 
       "/usr/local/rvm/gems/ruby-2.3.3/gems/activerecord-5.1.1/lib/active_record/associations/builder/association.rb:119:in `datacentre='" 
  • 當訪問項目的關係時,我可以看到它發生。例如,這是一個一個GET響應:
  • GET http://localhost:8060/datasets/

    { 
        "data": [ 
         { 
          "id": "5", 
          "type": "datasets", 
          "links": { 
           "self": "http://localhost:8060/datasets/5" 
          }, 
          "attributes": { 
           "created": "2011-03-02T16:41:20.000Z", 
           "doi": "10.5259/20070410230000/HTTP://www.STAFFSPASTTRACK.ORG.UK/EXHIBIT/CRIMEANDPUNISHMENT/IMAGEPAGE/ZERO.HTM", 
           "version": 0, 
           "is-active": "", 
           "updated": "2011-03-02T16:41:20.000Z", 
           "datacentre": "#<Datacentre:0x000000033389b8>", 
           "deposited": "2012-07-31T09:12:37.000Z" 
          }, 
          "relationships": { 
           "datacentre": { 
            "links": { 
             "self": "http://localhost:8060/datasets/5/relationships/datacentre", 
             "related": "http://localhost:8060/datasets/5/datacentre" 
            } 
           } 
          } 
         } 
    

    可以看到datacentre(foreign_key)屬性是如何呈現爲模型數據中心的對象類型。如果我嘗試訪問relantship該模型http://localhost:8060/datasets/5/datacentre我得到如下:

    { 
    * errors: [ 
    * { 
    * title: "Internal Server Error", 
    * detail: "Internal Server Error", 
    * code: "500", 
    * status: "500", 
    * meta: { 
    * exception: "Unknown source type #<Datacentre id: 10015, comments: "", contact_email: "[email protected]", contact_name: "Andy Jackson", created: "2010-12-14 22:05:32", doi_quota_allowed: 50000, doi_quota_used: 17, domains: "webarchive.org.uk", is_active: "\x01", name: "Web Archive Programme at BL", password: "98583c1bf114bfe80105f906d800e05325307f06b93ccee6b6...", role_name: "ROLE_DATACENTRE", symbol: "BL.WAP", updated: "2012-02-17 11:49:01", version: 2, allocator: 106, experiments: nil>", 
    * backtrace: [ 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/resource_serializer.rb:267:in `top_level_source_key'", 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/resource_serializer.rb:47:in `block in serialize_to_hash'", 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/resource_serializer.rb:47:in `map'", 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/resource_serializer.rb:47:in `serialize_to_hash'", 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/response_document.rb:109:in `results_to_hash'", 
    * "/usr/local/rvm/gems/ruby-2.3.3/gems/jsonapi-resources-0.9.0/lib/jsonapi/response_document.rb:12:in `contents’」, 
    

    我認爲問題是,API期待的錯誤類型的對象。它期望數據中心當它應該是期待數據中心資源

    我的設置如下:

    • 我有不遵循ActiveRecord的約定命名錶和foreign_keys舊的數據庫。
    • 表是單數,foreign_keys沒有_id後綴。
    • 我有問題的表格/模型具有one_to_many關係。
    • 關係是datacentre has_many datasets
    • 我正在使用jsonapi-resources和導軌5 api-only

    數據中心模型

    class Datacentre < ApplicationRecord 
        self.table_name = "datacentre" 
        alias_attribute :allocator_id, :allocator 
        has_and_belongs_to_many :prefixes, class_name: 'Prefix', join_table: "datacentre_prefixes", foreign_key: :prefixes, association_foreign_key: :datacentre 
        belongs_to :allocator, class_name: 'Allocator', foreign_key: :allocator 
        has_many :datasets 
    end 
    

    數據集模型

    class Dataset < ApplicationRecord 
        self.table_name = "dataset" 
        alias_attribute :datacentre_id, :datacentre 
        belongs_to :datacentre, class_name: 'Datacentre', foreign_key: :datacentre 
    end 
    

    數據中心資源

    class DatacentreResource < JSONAPI::Resource 
        model_name 'Datacentre' 
        model_hint model: Datacentre 
        attributes :comments, :contact_email, :contact_name, :created, :doi_quota_allowed, :doi_quota_used, :domains, :is_active, :name, :password, :role_name, :symbol, 
        :updated, :version, :experiments, :allocator 
        has_many :datasets 
        has_many :prefixes 
        has_one :allocator, class_name: 'Allocator', foreign_key: :allocator 
    end 
    

    dataset資源

    class DatasetResource < JSONAPI::Resource 
        model_name 'Dataset' 
        model_hint model: Dataset 
        attributes :created, :doi, :version, :is_active, :updated, :datacentre 
        attribute :deposited 
        has_one :datacentre, class_name: "Datacentre", foreign_key: :datacentre 
    end 
    

    到目前爲止,我已經解決了第一個問題(即通過修改datacentre的方法和其在數據集資源

    def datacentre(context=nil) 
        DatacentreResource.find_by_key(@model.datacentre.id) 
    end 
    
        def datacentre_id() 
        @model.datacentre.id 
    end 
    

    別名datacentre_id訪問的關係)但是,這不能解決POST問題。

    回答

    0

    我認爲這是導致錯誤

    class Dataset < ApplicationRecord 
        self.table_name = "dataset" 
        alias_attribute :datacentre_id, :datacentre 
        belongs_to :datacentre, class_name: 'Datacentre', foreign_key: :datacentre 
    end 
    

    datacentre_iddatacentre東西的別名,因此還給和響應對象datacentre回來,而不是datacentre_id

    可能它如果您刪除此行,將會啓用

    相關問題