1

I am trying to set up a relationship in my Rails application similar to the one in the following SO question. Rails Object Relationships and JSON Rendering

I want my JSON to be rendered in the same way as shown which is:

[    
    {
      "modelb": {
        "id": "1",
        "modela": [insert the ModelA JSON for ID's 1, 2 and 3]
      }
    {
      "modelb": {
        "id": "2",
        "modela": [insert the ModelA JSON for ID's 3, 4 and 5]
      }
    }
]

I already have a controller that creates the JSON necessary for Model A, as shown below, but I do not know how to make the ModelB model and controller in order to nest that information into another set of JSON or how to specify which ModelA objects go into which of ModelB's objects.

class JsonsController < ApplicationController
  before_action :set_json, only: [:show, :update, :destroy]

  # GET /jsons
  # GET /jsons.json
  def index
    @jsons = Json.all

    render json: @jsons
  end

  # GET /jsons/1
  # GET /jsons/1.json
  def show
    render json: @json
  end

  # POST /jsons
  # POST /jsons.json
  def create
    @json = Json.new(json_params)

    if @json.save
      render json: @json, status: :created, location: @json
    else
      render json: @json.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /jsons/1
  # PATCH/PUT /jsons/1.json
  def update
    @json = Json.find(params[:id])

    if @json.update(json_params)
      head :no_content
    else
      render json: @json.errors, status: :unprocessable_entity
    end
  end

  # DELETE /jsons/1
  # DELETE /jsons/1.json
  def destroy
    @json.destroy

    head :no_content
  end

  private

    def set_json
      @json = Json.find(params[:id])
    end

    def json_params
      params.require(:json).permit(:text, :parent, :id)
    end
end

Any resources or help would be appreciated.

Community
  • 1
  • 1
Kevin
  • 177
  • 1
  • 15
  • 1
    I think your going about this incorrectly. Why is your model named Json? It should be ModelB and then you can do @models = ModelB.find(params[:id]) then @models.to_json(:include => :modela) Posting your model code will help. Feel free to message if you want to chat about it – Alex Bezek May 20 '16 at 01:44
  • I have changed it to modelB, where would I put the code you're specifying? My model code is simply a has_many , belongs_to relationship as shown in the link referenced. Thanks – Kevin May 20 '16 at 06:52

1 Answers1

0

As @alexbezek already said you need to get ModelB in controller, but not Json

Rails have a great gem jbuilder that allow to render a json objects. You just create views for each json action.

Here is the example:

# Controller
# ...  
def index
  @models_b = ModelB.all
end
...

And view

#views/model_b/index.jbuilder

json.array! @models_b do |item|
  json.id item.id,
  json.modela: item.models_a
end

Or as just a possible approach you could define method as_json in each model you'd like to display as json. This is a "manual non-lazy" way to render your models as json objects.

For example:

# ModelB
def as_json
  jsn = {
    id: id,
    name: name,
    any_other_attr_you_need: any_other_attr_you_need
  }
jsn[:modela] = models_a.as_json if models_a.any?
end

#ModelA

def as_json
  jsn = {
    id: id,
    name: name,
    etc: etc
  }
  jsn
end


# Controller
# ...  
def index
  @models_a = ModelA.all
  render json: @models_a.as_json
end
...
retgoat
  • 2,414
  • 1
  • 16
  • 21
  • Thanks for your help, but I am following your examples and testing them and still dont understand. How does modelb in your example get the json from modelA to nest? – Kevin May 20 '16 at 06:50
  • So I started to get the as_json solution working, but in ModelB I am getting a NameError that says models_a is undefined local variable/method. Is there a way to fix this? – Kevin May 20 '16 at 07:16
  • Update: Was able to nest the JSON using the def as_json method, but it returns every model_a object nested in every model_b object, rather than being able to associate them where model_a objects belong to model_b objects, which has_many – Kevin May 20 '16 at 08:18
  • @Kevin, could you provide your models code? It's hard to find out the reason without it. Thanks. – retgoat May 20 '16 at 09:02