Rails'使用范围选择'嵌套模型

时间:2017-08-04 20:37:34

标签: ruby-on-rails ruby postgresql activerecord

我正在尝试创建一个Rails范围,它允许我按如下方式构建父子模型关联:

{
  id: 1,
  ...other_child_attrs,
  parent: {
    id: 2,
    ...other_parent_attrs
  }
}

我可以使用以下查询在parent中“注入”child属性:

scope :include_parent, -> { Child.joins(:parent).select('childs.*, parents.*') }

问题在于父级的嵌套属性是在与子属性相同的级别注入的(这可能会导致冲突,因为某些子属性在子级中重复出现 - id,{{1}等等):

created_at

是否可以单独使用active record / plain sql来实现上述结构(不必依赖序列化gem,{ id: 2, // Notice there's a parent - child id collision ...other_child_attrs, ...other_parent_attrs } 等)?

2 个答案:

答案 0 :(得分:0)

试试这个,在模型中使用as_json

 def as_json(options={})
     super(:include => { :sales => {
                               :include => { :product => {
                                             :only => [:id,:name, :price] } },
                               :only => :id} })
    end

答案 1 :(得分:0)

我认为你过于复杂了。如果你有两个模型正确配置了关联,那么你已经可以做你想做的事了:

class Child < ActiveRecord::Base
  belongs_to :parent
end

class Parent < ActiveRecord::Base
  has_one :child
end

parent = Parent.create
child = Child.create(parent_id: parent.id)

child.to_json(include: :parent)
 => [{"id":1,"parent_id":1,"created_at":"2017-08-04T20:48:52.056Z","updated_at":"2017-08-04T20:48:52.056Z","parent":{"id":1,"created_at":"2017-08-04T20:47:32.671Z","updated_at":"2017-08-04T20:47:32.671Z"}}]

child = Child.first
child.parent
  Child Load (0.2ms)  SELECT  "children".* FROM "children" ORDER BY "children"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Parent Load (0.1ms)  SELECT  "parents".* FROM "parents" WHERE "parents"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 => #<Parent id: 1, created_at: "2017-08-04 20:47:32", updated_at: "2017-08-04 20:47:32">