覆盖as_json以在深层嵌套模型中包含特定值

时间:2015-07-24 05:40:57

标签: ruby-on-rails

我有以下as_json查询:

render json: current_user.templates.limit(limit).offset(offset).as_json(
  :only => [:id, :name, :allow_title],
  :include => { :sections => {
    :only => [:id, :name],
    :include => { :columns => {
      :only => [:id],
      :include => { :fields => {
        :only => [:id, :name, :fieldtype],
        :include => [
          { :options => {
            :only => [:id, :name]
          }},
          { :values => {
            :only => [:id, :input, :field_id, :report_id]
          }}
        ]
      }}
    }}
  }}
)

我尝试了.includes / .joins / .wheres / etc的任意数量的组合来尝试复制它,只返回具有以下值的值:report_id =>零 我很确定我只能通过

来做到这一点
class Template

def as_json(options={})
  super(:only => [:id, :name, :allow_title],
    :include => { :sections => {
      :only => [:id, :name],
      :include => { :columns => {
        :only => [:id],
        :include => { :fields => {
          :only => [:id, :name, :fieldtype],
          :include => [
            { :options => {
              :only => [:id, :name]
            }},
            { :values => {
              :only => [:id, :input, :field_id],
              :include => { :report_id => nil }
            }}
          ]
        }}
      }}
    }}
  )
end

但我完全不知道如何修改as_json以获得我想要的东西。

1 个答案:

答案 0 :(得分:0)

目标是将Template.sections.columns.fields.values的值设置为仅绑定到Field的第一个Value(没有report_id,但下面的解决方案并不关心它):

class Template < ActiveRecord::Base
    has_many :sections

    scope :minned, ->{eager_load(:sections => {:columns => { :fields => [:values, :options]}})}  #Add this and use `templates.minned` for eager_loading goodness based off all the following as_json overrides

    def as_json(jsonoptions={})
        super(:only => [:id, :name, :allow_title]).merge(sections: sections)
    end
end

class Section < ActiveRecord::Base
    belongs_to :template, inverse_of: :sections
    has_many :columns

    def as_json(jsonoptions={})
        super(:only => [:id, :name, :template_id]).merge(columns: columns)
    end
end

class Column < ActiveRecord::Base
    belongs_to :section, inverse_of: :columns
    has_many :fields

    def as_json(jsonoptions={})
        super(:only => [:id, :section_id]).merge(fields: fields)
    end
end

class Field < ActiveRecord::Base
    belongs_to :column, inverse_of: :fields
    has_many :values
    has_many :options  

    def as_json(jsonoptions={})
        super(:only => [:id, :name, :fieldtype, :glyphicon, :required, :disabled, :column_id]).merge(options: options).merge(values: values.first) ## <-- This is where the goal is realized
    end
end

class Value < ActiveRecord::Base
    belongs_to :field, inverse_of: :values

    def as_json(jsonoptions={})
        super(:only => [:id, :input, :field_id])
    end
end

class Option < ActiveRecord::Base
    belongs_to :field, inverse_of: :options

    def as_json(jsonoptions={})
        super(:only => [:id, :name, :field_id])
    end
end