1

json をレンダリングするコントローラーがあります。コードは次のとおりです。

class AppLaunchDataController < ApiController
    def index
        service_types = []
        vendors = []
        tariffs = []
        fields = []
        vendors_hash = {}
        service_types_hash = {}
        tariffs_hash = {}
        fields_hash = {}

        @service_types = ServiceType.select("title, id").all.each do |service_type|
            service_types_hash = {id: service_type.id, title: service_type.title}
            service_types << service_types_hash
            @vendors = service_type.vendors.select("title, id").all.each do |vendor|
                vendors_hash = {id: vendor.id, title: vendor.title}
                vendors << vendors_hash
                @tariff = vendor.tariffs.select("title, id").all.each do |tariff|
                    tariffs_hash = {id: tariff.id, title: tariff.title}
                    tariffs << tariffs_hash
                    @fields  = tariff.fields.select("id, current_value, value_list").all.each do |field|
                        fields_hash = {id: field.id, current_value: field.current_value, value_list: field.value_list}
                        fields << fields_hash
                    end
                    tariffs_hash[:fields] = fields
                    fields = []
                end
                vendors_hash[:tariffs] = tariffs
                tariffs = []
            end
            service_types_hash[:vendors] = vendors
            vendors = []
        end
        render json: service_types
    end
end

戻り値は次のようになります。

[{"id":1,"title":"Water",
"vendors":[{"id":1,"title":"Vendor_1",
"tariffs":[{"id":1,"title":"Unlim",
"fields":[{"id":1,"current_value":"200","value_list":null},{"id":2,"current_value":"Value_1","value_list":"Value_1, Value_2, Value_3"}]},{"id":2,"title":"Volume",
"fields":[]}]},
{"id":2,"title":"Vendor_2",
"tariffs":[]}]},
{"id":2,"title":"Gas",
"vendors":[]},
{"id":3,"title":"Internet",
"vendors":[]}]

それは機能しますが、結果を得る別の (より多くのレール) 方法があると確信しています。誰かが以前に対処した場合は、助けてください。ありがとう。

4

1 に答える 1

0

ただ使う

# for eager-loading :
@service_types = ServiceType.includes( vendors: {tariffs: :fields} ) 
# now for the json :
@service_types.to_json( include: {vendors: {include: {tariffs: { include: :fields}}}} )

ServiceTypeオブジェクトが常にこの種の表現を持つ場合は、モデルのメソッドをオーバーライドするだけですas_json:

class ServiceType
  def as_json( options={} )
    super( {include: :vendors }.merge(options) ) # vendors, etc.
  end
end

これは Rails で推奨される方法です。to_jsonモデルを呼び出すとas_json、おそらく追加のオプションを使用して が呼び出されます。実際、as_jsonこのモデルの正規の json 表現について説明します。詳細については、API ドックを参照してくださいto_json

ニーズがより特殊な場合 ( selects を使用してクエリを高速化する場合など) は、いつでもto_json_for_app_launch_dataモデルで独自のメソッドをロールすることができます (を使用するかどうかに関係なくas_json)、またはプレゼンターでさらに優れています。

于 2013-01-28T13:09:02.400 に答える