简体   繁体   English

Rails使用范围的“选择为”嵌套模型

[英]Rails 'select as' nested model using scopes

I'm trying to create a Rails scope which allows me to structure a parent - child model association as follows: 我正在尝试创建一个Rails作用域,该作用域允许我构造父子模型关联,如下所示:

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

I was able to 'inject' the parent attributes in the child by using the following query: 我能“注入”的parent在属性child通过使用以下查询:

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

The issue is that the nested attributes of the parent are injected at the same level as the child attributes (which might cause collisions as some of the child attributes are repeated in the child - id , created_at , etc): 问题在于,父级的嵌套属性在与子级属性相同的级别上注入(这可能会导致冲突,因为某些子级属性在child- idcreated_at等中重复):

{
  id: 2, // Notice there's a parent - child id collision
  ...other_child_attrs,
  ...other_parent_attrs
}

Is it possible to achieve the structure explained above with active record/ plain sql alone (without having to rely on serialize gem, as_json , etc)? 是否可以仅使用活动记录/普通sql来实现上述结构(而不​​必依赖序列化gem, as_json等)?

try this, do it using as_json in the model 试试这个,在模型中使用as_json来做

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

I think that you are over-complicating this. 我认为您过于复杂了。 If you have two models properly configured with associations then you can already do what you want to do: 如果您已经正确配置了两个具有关联的模型,那么您已经可以做您想做的事情:

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">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM