Reputation: 3070
I'm learning Ruby on Rails (Specially for API development) and I need some help with something.
Lets say we have 2 tables, "Brands" and "Cars".
What I'm trying to do is basically:
Now, when I try to reach a car, it brings me:
{
"id": 1,
"name": "Veneno",
"brand_id": 1,
"created_at": "2016-12-03T21:47:01.000Z",
"updated_at": "2016-12-03T21:47:01.000Z"
}
My files contains the following: Migration files:
class CreateBrands < ActiveRecord::Migration[5.0]
def change
create_table :brands do |t|
t.string :name
t.timestamps
end
end
end
class CreateItems < ActiveRecord::Migration[5.0]
def change
create_table :items do |t|
t.string :name
t.integer :brand_id
t.timestamps
end
add_index :items, :brand_id
end
end
Models:
class Brand < ApplicationRecord
has_many :items
end
class Item < ApplicationRecord
belongs_to :brand
end
Currently, my items_controller.rb is:
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :update, :destroy]
# GET /items
def index
@items = Item.all
render json: @items
end
# GET /items/1
def show
render json: @item, :only => [:id, :name]
end
# POST /items
def create
@item = Item.new(item_params)
if @item.save
render json: @item, status: :created, location: @item
else
render json: @item.errors, status: :unprocessable_entity
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def item_params
params.require(:item).permit(:name, :brand_id)
end
end
Thank you! I'm online 24/7 to provide more info about this issue. I googled it a lot but I couldn't find out how to fix this.
Upvotes: 0
Views: 576
Reputation: 7522
What you're describing is how you want to serialize your model. There are gems that provide high-powered solutions to this problem (the venerable but still-relevant active_model_serializers
, for example), but for basic use-cases, you can get away with leveraging Rails' surprisingly-powerful as_json
.
For example, to make your show method include the brand object:
class ItemsController
# GET /items/1
def show
render json: @item, :includes => [:brand]
end
end
You can also override the default as_json at the model level, but that solution becomes tricky when different callers want different serializations and levels of detail. See Include associated model when rendering JSON in Rails for another example similar to what you're describing, but more involved.
Upvotes: 2