【问题标题】:Rails Active Model Serializer include in controller not injecting has many relationship in included parameterRails Active Model Serializer 包含在控制器中不注入在包含的参数中有很多关系
【发布时间】:2017-09-25 12:11:05
【问题描述】:

我看到有关 rails 5、活动模型序列化程序和 json-api 适配器的奇怪行为。

给定以下带有 Rolify gem 的 User 模型:

class User < ActiveRecord::Base
  #
  # Gem Includes
  #
  rolify


  # Include devise modules.
  devise :database_authenticatable,
      :recoverable, :rememberable, :trackable, :validatable
  include DeviseTokenAuth::Concerns::User

  #
  # Callbacks
  #
  after_create :assign_default_role

  #
  # Attributes
  #
  attr_accessor :remote_image

  #
  # Validations
  #
  validates :name, presence: true, length: {in: 1..100}
  validates :last_name, presence: true, length: {in: 1..100}
  validates :role_ids, presence: true, on: :update

  #
  # Relations
  #
  belongs_to :current_scenario, class_name: "Scenario"


  #
  # Private Instance Methods
  #
  def assign_default_role
    self.add_role(:user) if self.roles.blank?
  end

end

以及以下控制器代码:

def show
  @user = User.find(params[:id])
  authorize @user
  render json: @user, include: ['roles'], status: :ok
end

如您所见,我将要呈现的角色关系作为 json api 响应的一部分,使用 json-api 适配器格式。

仅供参考,UserSerializer

class UserSerializer < ActiveModel::Serializer
  #
  # Attributes
  #
  attributes :id, :email, :name, :last_name, :image_url, :image_thumb_url, :created_at, :updated_at, :current_scenario_id, :last_sign_in_at

  #
  # Relations
  #
  has_one :current_scenario
  has_many :roles

  #
  # Methods
  #
  def image_url
    object.image_url
  end

  def image_thumb_url
    object.image_url(:thumb)
  end
end

在检索 json 响应时,我得到以下信息:

{
  "data": {
    "id":"2",
    "type":"users",
    "attributes": {
      "email":"talvarez@igaltex.com.ar", ...
    },
    "relationships": {
      "current-scenario": {
        "data": {
          "id":"204",
          "type":"scenarios"
        }
      },
      "roles": {
        "data": [
          {
            "id":1,
            "name":"user",
            "resource-type":null,
            "resource-id":null,
            "created-at":"2017-01-23T10:27:08.707-03:00",
            "updated-at":"2017-01-23T10:27:08.707-03:00"
          },
          {
            "id":2,
            "name":"admin",
            "resource-type":null,
            "resource-id":null,
            "created-at":"2017-01-24T09:40:53.020-03:00",
            "updated-at":"2017-01-24T09:40:53.020-03:00"
          }
        ]
      }
    }
  }
}

如您所见,包含的关系角色及其所有属性位于 json-api 响应的 relationships 片段中。角色数据不应该在 included 片段中吗?顺便说一句,这是缺失的?此外,在关系片段 roles 内部应该仅作为参考出现,例如:{relationships: {roles: [{id: "1", type: "role"}, {id: "2", type: "role"}]} 我错了吗?

为了对比这一点,看看同时包含current_scenario 关系时会发生什么:

{
  "data": {
    "id":"2",
    "type":"users",
    "attributes": {
      "email":"talvarez@igaltex.com.ar",
      "name":"Tomás",
      "last-name":"Alvarez", 
      ...
    },
    "relationships": {
      "current-scenario": {
        "data": {
          "id":"204",
          "type":"scenarios"
        }
      },
      "roles": {
        "data": [
          {
            "id":1,
            "name":"user",
            "resource-type":null,
            ...
          }
        ]
      }
    },
    "included": [
      {
        "id":"204",
        "type":"scenarios",
        "attributes": {
          "name":"Scenario reload II",
          "description":null,
          "created-at":"2017-04-18T11:55:35.242-03:00",
          "updated-at":"2017-04-18T11:55:35.242-03:00"
        },
        "relationships": {
          "scenario-stocks": {
            "data":[]
          }
        }
      }
    ]
  }
}

查看包含的片段现在如何显示有关 current_scenario 的所有信息,并且只有对 current_scenario 的引用被添加到 relationships 片段中。这是因为角色是活动模型序列化程序中的 has_many 关系,而 current_scenariobelongs_to 吗?我对 json-api 适配器规范的理解有误吗?

非常感谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5 active-model-serializers json-api


    【解决方案1】:

    哎哟。 JSON-API 响应中的不一致是因为我忘记在后端添加角色模型序列化程序(Rails 5)。这是现在的 json 响应,这是我一直在寻找的:

    {
    "data": {
        "id": "2",
        "type": "users",
        "attributes": {
            "email": "talvarez@igaltex.com.ar",
            "name": "Tomás",
            "last-name": "Alvarez",
            "image-url": "http://localhost:3001/uploads/user/image/2/05a4dc7.jpg",
            "image-thumb-url": "http://localhost:3001/uploads/user/image/2/thumb_05a4dc7.jpg",
            "created-at": "2017-01-23T10:39:12.485-03:00",
            "updated-at": "2017-04-25T16:32:14.610-03:00",
            "current-scenario-id": 204,
            "last-sign-in-at": "2017-04-25T16:29:03.559-03:00"
        },
        "relationships": {
            "current-scenario": {
                "data": {
                    "id": "204",
                    "type": "scenarios"
                }
            },
            "roles": {
                "data": [{
                    "id": "1",
                    "type": "roles"
                }, {
                    "id": "2",
                    "type": "roles"
                }]
            }
        }
    },
    "included": [{
        "id": "204",
        "type": "scenarios",
        "attributes": {
            "name": "Scenario reload II",
            "description": null,
            "created-at": "2017-04-18T11:55:35.242-03:00",
            "updated-at": "2017-04-18T11:55:35.242-03:00"
        },
        "relationships": {
            "scenario-stocks": {
                "data": []
            }
        }
    }, {
        "id": "1",
        "type": "roles",
        "attributes": {
            "name": "user"
        }
    }, {
        "id": "2",
        "type": "roles",
        "attributes": {
            "name": "admin"
        }
    }]
    

    }

    【讨论】:

      【解决方案2】:

      抱歉这个错误。当没有找到序列化程序时,我们还没有弄清楚如何确定关系的类型。如果遇到异常会更有帮助吗?

      【讨论】:

      • 当然,除了一个例外,我会立即注意到我忘记添加序列化程序并很快修复错误。
      【解决方案3】:

      这就是JSON API 的工作方式,您无法在“一个对象”中检索所需的模型+关系。关系总是分开的。所以你需要以某种方式“粘合”它。您可以使用可以帮助您的gem,或者您可以在前端执行它(所有大型框架都支持它)。 一般来说,这种带有“关系”的方法看起来很奇怪,但是当您拥有具有大量依赖项的复杂对象时,这是唯一可行的方法。

      【讨论】:

      • 我认为您误解了这个问题。问题是,为什么对于 current_scenario,在使用 include: ['current_scenario'] 时,在来自控制器的 json 响应中,它的所有数据都添加到了 included 片段中json 响应,但在包含“角色”时没有发生同样的情况。
      • 找到答案@nautgrad。检查我上面的答案,我明天会在stackoverflow允许时接受它。
      猜你喜欢
      • 1970-01-01
      • 2018-09-15
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多