ruby-on-rails - 在 Rails 中动态包含对象的关联

标签 ruby-on-rails json ruby ruby-on-rails-5 ruby-2.4

我目前正在开发一个小型 Rails 5 应用程序,我需要根据某些事件将 ActiveRecord 对象传递给外部服务。在我的模型中,我定义了以下内容:

# /models/user.rb
after_create :notify_external_service_of_user_creation

def notify_external_service_of_user_creation
  EventHandler.new(
    event_kind: :create_user,
    content: self
  )
end

EventHandler 然后将此对象转换为 JSON,并通过 HTTP 请求将其发送到外部服务。通过在对象上调用 .to_json 这会呈现一个 JSON 输出,看起来像这样:

{
  "id":1234,
  "email":"test@testemail.dk",
  "first_name":"Thomas",
  "last_name":"Anderson",
  "association_id":12,
  "another_association_id":356
}

现在,我需要一种方法将所有一级关联直接包含到其中,而不仅仅是显示 foreign_key。所以我正在寻找的结构是这样的:

{
  "id":1234,
  "email":"test@testemail.dk",
  "first_name":"Thomas",
  "last_name":"Anderson",
  "association_id":{
    "attr1":"some_data",
    "attr2":"another_value"
  },
  "another_association_id":{
    "attr1":"some_data",
    "attr2":"another_value"
  },
}

我的第一个想法是像这样反射(reflect)模型:object.class.name.constantize.reflect_on_all_associations.map(&:name),其中 object 是一个在这种情况下是用户的实例,并使用此列表遍历关联并将它们包含在输出中。虽然这看起来相当乏味,所以我想知道是否有更好的方法使用 Ruby 2.4 和 Rails 5 来实现这一目标。

最佳答案

如果您不想使用外部序列化器,您可以为每个模型覆盖 as_jsonas_jsonto_json 调用。

module JsonWithAssociations
  def as_json
    json_hash = super

    self.class.reflect_on_all_associations.map(&:name).each do |assoc_name|
      assoc_hash = if send(assoc_name).respond_to?(:first)
                     send(assoc_name).try(:map, &:as_json) || [] 
                   else
                     send(assoc_name).as_json 
                   end

      json_hash.merge!(assoc_name.to_s => assoc_hash)
    end 

    json_hash
  end
end

您需要预先添加 这个特定模块,以便它覆盖默认的as_json 方法。

User.prepend(JsonWithAssociations)

class User
  prepend JsonWithAssociations
end

关于ruby-on-rails - 在 Rails 中动态包含对象的关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41777067/

相关文章:

ruby - 在 Ruby 中创建带有静态页面的博客的最佳方式

ruby-on-rails - rails4 将搜索引擎放在主页中

ruby-on-rails - 每个用户在 Rails 中使用片段缓存

android - 如何用 Volley 解析 JSON?

php - 在 MySQL 中,通过对 JSON 列执行联接从两个表中获取数据时出现问题

Ruby 检索字符串中的一组字符串

ruby-on-rails - 如何在 Rails 中将自定义错误返回到我的表单?

ruby-on-rails - 当其他属性发生变化时如何更新一个属性

arrays - 在 JSON-LD 文件中过滤具有特定 JSON 值的键

ruby - 明确地产生 n 值给 Symbol#to_proc