I want to have multiple classes inside grape entity file, this is the folder structure app/api/proj/api/v2/entities/committees.rb
module PROJ::API::V2::Entities
class Committee < Grape::Entity
expose :id
expose :name, :full_name, :email, :tag, :parent_id
expose :country do |entity, option|
entity.parent.name if entity.parent.present?
end
# include Urls
private
def self.namespace_path
"committees"
end
end
class CommitteeWithSubcommittees < CommitteeBase
# include ProfilePhoto
expose :suboffices, with: 'PROJ::API::V2::Entities::CommitteeBase'
end
and inside the Grape API
present @committees, with: PROJ::API::V2::Entities::Committee
is working. but if I present with
present @committees, with: PROJ::API::V2::Entities::CommitteeList
It is not working. But it works when I move it to a new file named committee_list.rb
inside entities.
You seem to be missing some key information from your post because you have not defined a class named CommitteeList
or CommitteeBase
anywhere. I assume that you have defined them and that you did not supply that code.
The problem that you're running into has to do with how Rails autoloads classes. There is more information available elsewhere on this, but essentially you should ensure that your class names, modules names, directory names, and file names all match up. The reason that it works when you move your CommitteeList
class to its own file is because Rails is able to find the class dynamically.
I've had to do some guess-work based on what you provided, but you want something that looks like this:
# app/api/proj/api/v2/entities/committee.rb
module PROJ::API::V2::Entities
class Committee < Grape::Entity; end
end
# app/api/proj/api/v2/entities/committee_base.rb
module PROJ::API::V2::Entities
class CommitteeBase; end
end
# app/api/proj/api/v2/entities/committee_with_subcommittee.rb
module PROJ::API::V2::Entities
class CommitteeWithSubcommittee < CommitteeBase; end
end
# app/api/proj/api/v2/entities/committee_list.rb
module PROJ::API::V2::Entities
class CommitteeList < CommitteeBase; end
end
Note that in this example I have renamed some things; your class names should be singular (committee
not committees
) and the filenames should match them, but making that change may cause other issues in your app. Generally, you should use singular and not plural.
I recommend reading the Rails guide entry on constants and autoloading for more detail.
Updated:
In your gist you say that you get Uninitialized constant PROJ::API::V2::Entities::CommitteeOffice
when you run present @committees, with: PROJ::API::V2::Entities::CommitteeOffice
with the following code:
# app/api/proj/api/v2/entities/committee_base.rb
module PROJ::API::V2::Entities
class CommitteeBase < Grape::Entity;
expose :id
end
class CommitteeOffice < CommitteeBase;
expose :name
end
end
You get this error because Rails will only look for the class named PROJ::API::V2::Entities::CommitteeBase
in the file entities/committee_base.rb
. If you prefer to use a single monolithic file for your entity classes, then you must name the above file app/api/proj/api/v2/entities.rb
.
By naming the file app/api/proj/api/v2/entities.rb
, it tells Rails "This file contains the module Entities
and all its classes."