How to build a JSON response made up of multiple models in Rails

后端 未结 4 405
-上瘾入骨i
-上瘾入骨i 2020-12-28 20:33

First, the desired result

I have User and Item models. I\'d like to build a JSON response that looks like this:

{
  \"use         


        
相关标签:
4条回答
  • 2020-12-28 20:41

    Incase anyone is looking for an alternative solution for this, this is how I solved this in Rails 4.2:

    def observe
      @item = some_item
      @user = some_user
    
      respond_to do |format|
        format.js do
          serialized_item = ItemSerializer.new(@item).attributes
          serialized_user = UserSerializer.new(@user).attributes
          render :json => {
            :item => serialized_item, 
            :user => serialized_user
          }
        end
      end
    end
    

    This returns the serialized version of both objects as JSON, accessible via response.user and response.item.

    0 讨论(0)
  • 2020-12-28 20:44

    Working answer #2 To avoid the issue of your json being "escaped", build up the data structure by hand, then call to_json on it once. It can get a little wordy, but you can do it all in the controller, or abstract it out to the individual models as to_hash or something.

    def observe
      respond_to do |format|
        format.js do
          render :json => {
            :user => {:username => current_user.username, :foo => current_user.foo, :bar => current_user.bar},
            :items => @items.collect{ |i| {:id => i.id, :name => i.name, :zim => i.zim, :gir => i.gir} }
          }
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-28 20:49

    EDITED to use as_json instead of to_json. See How to override to_json in Rails? for a detailed explanation. I think this is the best answer.

    You can render the JSON you want in the controller without the need for the helper model.

    def observe
      respond_to do |format|
        format.js do
          render :json => {
            :user => current_user.as_json(:only => [:username], :methods => [:foo, :bar]),
            :items => @items.collect{ |i| i.as_json(:only => [:id, :name], :methods => [:zim, :gir]) }
          }
        end
      end
    end
    

    Make sure ActiveRecord::Base.include_root_in_json is set to false or else you'll get a 'user' attribute inside of 'user'. Unfortunately, it looks like Arrays do not pass options down to each element, so the collect is necessary.

    0 讨论(0)
  • There are a lot of new Gems for building JSON now, for this case the most suitable I have found is Jsonify:

    https://github.com/bsiggelkow/jsonify https://github.com/bsiggelkow/jsonify-rails

    This allows you to build up the mix of attributes and arrays from your models.

    0 讨论(0)
提交回复
热议问题