【问题标题】:Rails LEFT JOIN searching and jsonRails LEFT JOIN 搜索和 json
【发布时间】:2017-04-06 13:50:12
【问题描述】:

我有以下型号:

class Address < ActiveRecord::Base
  has_many :service_records
  attr_accessor :service_record
end

class ServiceRecord < ActiveRecord::Base
  belongs_to :address
  belongs_to :plant
end

class Plant < ActiveRecord::Base
  has_one :service_record
end

我想执行一个查询,左连接地址上的每个服务记录和服务记录上的每个工厂。因此,例如,如果我有一个包含 3 个服务记录的地址,我希望获得 3 个结果,这些结果重复每个服务记录的地址字段,同时还包含每个服务记录的工厂信息。

到目前为止,我的查询看起来像这样(使用 Rails 5):

Address.left_joins(service_records: :plant)

这会返回正确数量的重复地址结果(即上面示例中的 3 个)。

我正在努力弄清楚的下一步是将生成的查询作为 JSON 结构返回,其中包含每个地址和每个唯一的服务记录。所以是这样的:

[
  {
    id: 1,
    address: "1234 Street Rd",
    service_record: {
      id: 1
      plant: {
        id: 1
      }
    }
  },
  {
    id: 1,
    address: "1234 Street Rd",
    service_record: {
      id: 2
      plant: {
        id: 2
      }
    }
  },
  {
    id: 1,
    address: "1234 Street Rd",
    service_record: {
      id: 3
      plant: {
        id: 3
      }
    }
  }
]

如果您注意到,我的地址模型上确实有一个 attr_accessor :service_record,但是我不确定这是获得所需内容的正确方法。任何帮助或替代方法来获得我正在寻找的东西将不胜感激!

【问题讨论】:

    标签: mysql ruby-on-rails activerecord ruby-on-rails-5


    【解决方案1】:

    从您的查询中,您可以使用带有选项的 Rails as_json 来实现您想要的。你可以这样做:

    addresses = Address.left_joins(service_records: :plant)
    addresses.as_json
    # => [
      {
        id: 1,
        address: "1234 Street Rd"
      },
      {
        id: 1,
        address: "1234 Street Rd"
      },
      {
        id: 1,
        address: "1234 Street Rd"
      }
    ]
    

    下一步是添加关联

    addresses.as_json(include: :service_record)
    [
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 1
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 2
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 3
        }
      }
    ]
    

    最后:

    addresses.as_json(include: { service_record: { include: :plant } })
    # => [
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 1
          plant: {
            id: 1
          }
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 2
          plant: {
            id: 2
          }
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 3
          plant: {
            id: 3
          }
        }
      }
    ]
    

    然后您可以微调结果。更多信息请访问documentation。

    更新

    如果您确定 service_records 数组中只有一条记录,您可以这样做:

    def service_record
      service_records.first
    end
    

    然后这样做

    addresses.as_json(methods: :service_record)
    [
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 1
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 2
        }
      },
      {
        id: 1,
        address: "1234 Street Rd",
        service_record: {
          id: 3
        }
      }
    ]
    

    【讨论】:

    • service_record 不是地址模型上的“官方”属性。我只能访问service_records,因为这是模型之间的关联。
    • 为什么要设置service_record attr_accessor?
    • 我补充说这是一个可能的想法。我目前没有在任何地方设置它。我希望有一种方法可以将其设置为等于在查询期间加入地址的service_record,但看起来这是不可能的。
    • 如果你确定你只有一个 service_record,你可以有一个方法。我会更新我的答案,告诉你怎么做。
    • 这就是问题所在,我不确定是否只有一个。每个地址可以有零个、一个或多个服务记录,我需要为每个具有相应地址的 json 条目。
    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2011-10-13
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    相关资源
    最近更新 更多