简体   繁体   中英

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:

{
  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:

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):

{
  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)?

try this, do it using as_json in the model

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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