Reputation: 51824
I am working on a project which uses some inheritance structure ... The base class is ..
# /app/models/shape.rb
class Shape < ActiveRecord::Base
acts_as_superclass # https://github.com/mhuggins/multiple_table_inheritance
end
A subclass is ...
# /app/models/circle.rb
class Circle < ActiveRecord::Base
inherits_from :shape
end
Here is a graphic showing the inheritance structure.
For these models I am trying to create an API using the RABL gem. Here are the relevant controllers ...
# /app/controllers/api/v1/base_controller.rb
class Api::V1::BaseController < InheritedResources::Base
load_and_authorize_resource
respond_to :json, except: [:new, :edit]
end
...
# /app/controllers/api/v1/shapes_controller.rb
class Api::V1::ShapesController < Api::V1::BaseController
actions :index
end
end
...
# /app/controllers/api/v1/circles_controller.rb
class Api::V1::CirclesController < Api::V1::BaseController
def index
@circles = Circle.all
end
def show
@circle = Circle.find(params[:id])
end
end
I created a show
template as suggested in Railscast #322 of Ryan Bates. It looks like this ...
# /app/views/circles/show.json.rabl
object @circle
attributes :id
When I request a circle via http://localhost:3000/api/v1/circles/1.json
the following error message is shown ...
Template is missing
Missing template api/v1/circles/show, api/v1/base/show, inherited_resources/base/show, application/show with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :arb, :haml, :rabl]}.
How do I need to setup the templates in order to work with the inherited resources?
I came up with the following views. I also managed to implement the inheritance structure of the models to keep the code DRY.
# views/api/v1/shapes/index.json.rabl
collection @shapes
extends "api/v1/shapes/show"
...
# views/api/v1/shapes/show.json.rabl
object @place
attributes :id, :area, :circumference
...
# views/api/v1/circles/index.json.rabl
collection @circles
extends "api/v1/circles/show"
...
# views/api/v1/circles/show.json.rabl
object @circle
extends "api/v1/shapes/show"
attributes :radius
if action_name == "show"
attributes :shapes
end
This outputs the desired JSON for the circles (index
action):
# http://localhost:3000/api/v1/cirles.json
[
{
"id" : 1,
"area" : 20,
"circumference" : 13,
"radius" : 6
},
{
"id" : 2,
"area" : 10,
"circumference" : 4,
"radius: 3
}
]
But it does not output the associated shapes
with all attributes for some reason ...
Note: There is a association on the Shape
model which I did not mention before.
# http://localhost:3000/api/v1/cirles/1.json
{
"id" : 1,
"area" : 20,
"circumference" : 13,
"radius" : 6,
"shapes" : [
{
"id" : 2,
"created_at" : "2013-02-09T12:50:33Z",
"updated_at" : "2013-02-09T12:50:33Z"
}
]
},
Upvotes: 0
Views: 1126
Reputation: 766
According to the data you provided, you put the templates in /app/views/circles
. The error is telling you that you need to put them in /app/views/api/v1/circles
instead I believe.
For the second question, it sounds like you are saying each circle has_many associated shapes. In that case, I believe something like the following should give what you want for views/api/v1/circles/show.json.rabl
:
# views/api/v1/circles/show.json.rabl
object @circle
extends 'api/v1/shapes/show'
attributes :radius
child(:shapes) do
extends 'api/v1/shapes/show'
end
Upvotes: 1