Open chadwtaylor opened 9 years ago
Have you looked into the ::represents
class method, yet? https://github.com/apotonick/roar-rails#represents-configuration
Since each method will vary in which model will be rendered (ie: most of the time a person model, rarely will be an invoice model). So putting it on the class level may not be favorable in my situation? I gave it a try though and got another error: undefined method 'id' for #<Array:0x007fde1099e670>
I'm hoping I can create one PersonRepresenter that will deal with collections as well, hence the represent_items_with
at the method level.
Thanks for your invaluable help!
I'm still wondering, though, why the :represent_items_with
option doesn't kick in?
What else do you need to see from my end to narrow down the issue?
I even tried to change from render json: people, represent_items_with:Api::V2::PersonRepresenter
to respond_with people, represent_items_with:Api::V2::PersonRepresenter
and got the following error:
ActionController::UnknownFormat
Am hitting a wall here but going to try few more things and hopefully get the collections to work (emphasis: The single model worked nicely).
Ah, I got it! The :represent_items_with
option doesn't work with render
! If you use respond_with
you gotta call respond_to
on the controller level (that's Rails, not roar-rails!)!
I switched to respond_with
with the respond_to
on the controller level (see my codes below) -- and got this error:
ActionController::UnknownFormat
The only thing working for me is using render
(on a single model). Any ideas?
# app/api/v2/people_controller.rb
class Api::V2::PeopleController < Api::V2::ApiController
include Roar::Rails::ControllerAdditions
respond_to :json
def index
p = Person.first
respond_with p #=> This resulted in ActionController::UnknownFormat
end
end
# app/representers/api/v2/person_representer.rb
module Api
module V2
module PersonRepresenter
include Roar::JSON::JSONAPI
type :people
property :id
property :first_name
property :last_name
property :full_name
end
end
end
Can you paste the server output or the test line for that failling request? It must be something in Rails, we don't throw UnknownFormat
anywhere! Thanks!
Started GET "/v2/people" for 127.0.0.1 at 2015-02-03 14:15:35 -0800
Processing by Api::V2::PeopleController#index as HTML
Person Load (0.5ms) SELECT "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT 1
Completed 406 Not Acceptable in 3ms
ActionController::UnknownFormat - ActionController::UnknownFormat:
responders (2.1.0) lib/action_controller/respond_with.rb:205:in `respond_with'
app/controllers/api/v2/people_controller.rb:12:in `index'
actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.2.0) lib/abstract_controller/base.rb:137:in `process'
actionview (4.2.0) lib/action_view/rendering.rb:30:in `process'
actionpack (4.2.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal.rb:236:in `block in action'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:42:in `serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/agent_hooks.rb:26:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/browser_monitoring.rb:23:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/developer_mode.rb:56:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
rack (1.6.0) lib/rack/etag.rb:24:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/conditionalget.rb:25:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/head.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
appsignal (0.11.0) lib/appsignal/rack/listener.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
airbrake (4.1.0) lib/airbrake/rails/middleware.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
better_errors (2.0.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
better_errors (2.0.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
better_errors (2.0.0) lib/better_errors/middleware.rb:57:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/runtime.rb:18:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rocket_pants (1.10.0) lib/rocket_pants/cache_middleware.rb:21:in `_call'
rocket_pants (1.10.0) lib/rocket_pants/cache_middleware.rb:12:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/lock.rb:17:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack-cors (0.3.1) lib/rack/cors.rb:72:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
airbrake (4.1.0) lib/airbrake/user_informer.rb:16:in `_call'
airbrake (4.1.0) lib/airbrake/user_informer.rb:12:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
hirefire-resource (0.3.4) lib/hirefire/middleware.rb:29:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
railties (4.2.0) lib/rails/engine.rb:518:in `call'
railties (4.2.0) lib/rails/application.rb:164:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/content_length.rb:15:in `call'
puma (2.9.2) lib/puma/server.rb:490:in `handle_request'
puma (2.9.2) lib/puma/server.rb:361:in `process_client'
puma (2.9.2) lib/puma/server.rb:254:in `block in run'
puma (2.9.2) lib/puma/thread_pool.rb:92:in `block in spawn_thread'
(want to say how much I appreciate your help here!)
"No worries, mate!" as they say in Australia! :wink:
This is your problem: Processing by Api::V2::PeopleController#index as HTML
Your request is not a JSON request! That's why Rails complains, it doesn't know how to handle a generic HTML request.
Ah, so I appended .json
to the url like so: http://localhost:3001/v2/people.json
and a new error came up:
Started GET "/v2/people.json" for 127.0.0.1 at 2015-02-03 14:25:17 -0800
Processing by Api::V2::PeopleController#index as JSON
Person Load (0.3ms) SELECT "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 18ms
NoMethodError - undefined method `default_render' for #<Api::V2::PeopleController:0x007fdf3bb770d8>:
responders (2.1.0) lib/action_controller/responder.rb:236:in `default_render'
responders (2.1.0) lib/action_controller/responder.rb:186:in `to_format'
responders (2.1.0) lib/action_controller/responder.rb:163:in `respond'
responders (2.1.0) lib/action_controller/responder.rb:156:in `call'
responders (2.1.0) lib/action_controller/respond_with.rb:203:in `respond_with'
app/controllers/api/v2/people_controller.rb:12:in `index'
actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.2.0) lib/abstract_controller/base.rb:137:in `process'
actionview (4.2.0) lib/action_view/rendering.rb:30:in `process'
actionpack (4.2.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal.rb:236:in `block in action'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:42:in `serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/agent_hooks.rb:26:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/browser_monitoring.rb:23:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/rack/developer_mode.rb:56:in `traced_call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:55:in `call'
rack (1.6.0) lib/rack/etag.rb:24:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/conditionalget.rb:25:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/head.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
appsignal (0.11.0) lib/appsignal/rack/listener.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
airbrake (4.1.0) lib/airbrake/rails/middleware.rb:13:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
better_errors (2.0.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
better_errors (2.0.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
better_errors (2.0.0) lib/better_errors/middleware.rb:57:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/runtime.rb:18:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rocket_pants (1.10.0) lib/rocket_pants/cache_middleware.rb:21:in `_call'
rocket_pants (1.10.0) lib/rocket_pants/cache_middleware.rb:12:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/lock.rb:17:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack-cors (0.3.1) lib/rack/cors.rb:72:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
airbrake (4.1.0) lib/airbrake/user_informer.rb:16:in `_call'
airbrake (4.1.0) lib/airbrake/user_informer.rb:12:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
hirefire-resource (0.3.4) lib/hirefire/middleware.rb:29:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
railties (4.2.0) lib/rails/engine.rb:518:in `call'
railties (4.2.0) lib/rails/application.rb:164:in `call'
newrelic_rpm (3.9.7.266) lib/new_relic/agent/instrumentation/middleware_tracing.rb:57:in `call'
rack (1.6.0) lib/rack/content_length.rb:15:in `call'
puma (2.9.2) lib/puma/server.rb:490:in `handle_request'
puma (2.9.2) lib/puma/server.rb:361:in `process_client'
puma (2.9.2) lib/puma/server.rb:254:in `block in run'
puma (2.9.2) lib/puma/thread_pool.rb:92:in `block in spawn_thread'
I hate Rails.
What roar-rails version are you on?
roar 1.0.0
roar-rails 1.0.1
rails 4.2.0
I love Rails. :)
That's because you haven't seen how simple things can be with less Rails: https://leanpub.com/trailblazer
I'm pretty sure -- the thing is we're knee-deep into a Rails project... so we can't switch boats just yet. :(
I hear ya! :stuck_out_tongue_winking_eye:
Trailblazer is Rails, just less coupling to the actual framework and less weirdness going on in controllers and models.
I really have no idea what's going on on your side - I checked an tests pass with Rails 4.2 and roar-rails. Are you using rails-api?
AH, I know what's your problem.
You got a file app/views/v2/peoples/index.html.haml
and that makes it try to call render_default
and this is exactly why I hate Rails.
Explanation: Rails and its responders use exceptions to find out whether or not a template is present and then base further behavior on that. And that is just wrong as it is completely hidden semantic, but, hey, magic, yeah, FTW! :stuck_out_tongue:
Correct, am using rails-api and the file index.html.haml doesn't even exist... this is so weird. Yea, FTW, will continue to play around and get something going! :)
Thanks!
Are there any files in your app/views
? See, this is where the wrong flow starts: https://github.com/plataformatec/responders/blob/master/lib/action_controller/responder.rb#L190
Wait, what was your actual problem in the first place? We can make that work and you keep using render
?
Yes, I have views but they're for mailers only (ie: app/view/person_mailer).
My issue was trying to keep one representer for each models (rather than creating two for each model like PersonRepresenter
and PeopleRepresenter
).
I even created a PeopleRepresenter
and used render
, it found the PeopleRepresenter file but I got this error: undefined method 'id' for #<Array:0x007fe3277c3ac8>
I wonder though if the people_representer.rb
is supposed to have a certain implementation? I basically copied-pasted-renamed from person_representer.rb
to people_representer.rb
.
It sounds like your representers for singular models are ok. However, you need to define a representer for collections, too (or use represent_items_with
, which isn't implemented for render
, YET cough wink).
Do you have a sample of what a representer for collections should look like?
Yea, represent_items_with
for render
would be awesome… one day! :)
Tons of examples in issues, check Lonely Collections. Or buy my book and wait a few weeks until we get to the document API parts. _cough_ _COUGH_*
:)
Ah, thanks for the Lonely Collection tip -- I overlooked that!
Now things are rendering for collections high five and there's a but... Here's what the result looked like:
[
{
"people":{
"id":8,
"first_name":"Jane",
"last_name":"Doe",
"full_name":"Jane Doe",
}
},
{
"people":{
"id":18,
"first_name":"John",
"last_name":"Doe",
"full_name":"John Doe",
}
}
]
I would think it should look like this...
{
people: [
{
id: 8,
first_name: "Jane",
last_name: "Doe",
full_name: "Jane Doe",
},
{
id: 18,
first_name: "John",
last_name: "Doe",
full_name: "John Doe",
}
]
}
Here's what my PeopleRepresenter looks like:
module Api
module V2
class PeopleRepresenter < Roar::Decorator
include Representable::JSON::Collection
items extend:Api::V2::PersonRepresenter, class:Person
end
end
end
Your PersonRepresenter
must have a representation_wrap
set?
Ah, thanks... just added self.represenation_wrap = :people
and we are so close... Here's the new JSON payload:
{
people: [
{
"people":{
"id":8,
"first_name":"Jane",
"last_name":"Doe",
"full_name":"Jane Doe",
}
},
{
"people":{
"id":18,
"first_name":"John",
"last_name":"Doe",
"full_name":"John Doe",
}
}
]
}
Haha, no, I am saying Api::V2::PersonRepresenter
should NOT have a representation wrap set, otherwise it will add it for every item. Paste Api::V2::PersonRepresenter
.
(will paste soon; BTW just bought your book....)
Good man, thanks! I promise lots of content about Roar, soon!
I commented out type :people
in PersonRepresenter
and now the collection is rendering the JSON payload correctly.
However, I need to keep type :people
for a single JSON payload, what to do?
Here's the person_representer.rb
content:
module Api
module V2
class PersonRepresenter < Roar::Decorator
include Roar::JSON::JSONAPI
# type :people # commented that line to make PeopleRepresenter wrap correctly; but need this for a single model, what to do?
property :id
property :first_name
property :last_name
property :full_name
end
end
end
We are almost there... the current issue is that the type
has to be in PersonRepresenter
for single models to show:
{
people: {
id: 8,
first_name: "Jane",
...
}
}
Am I making sense?
So close; and then I'll be able to continue my merry way in building an Ember.js frontend.
Thanks so much for your patience and support!
Update: As a temporary unfavorable workaround was implementing three files:
PersonRepresenter
- this has type :people
PersonUnwrapRepresenter
- a copy of PersonRepresenter sans type
PeopleRepresenter
- will call PersonUnwrapRepresenter instead.
Obviously not a good practice but that's something I could get some work done while waiting to see what you have to say.
BTW, loved your intro in your book -- the Rails date! I first used it in 2008 so you're two years ahead of me.
Just in case, I'm sharing my current implementations:
PersonRepresenter:
module Api
module V2
class PersonRepresenter < Roar::Decorator
include Roar::JSON::JSONAPI
type :people
property :uuid, as: :id
property :first_name
property :last_name
property :full_name
end
end
end
PersonUnwrapRepresenter:
module Api
module V2
class PersonRepresenter < Roar::Decorator
include Roar::JSON::JSONAPI
property :uuid, as: :id
property :first_name
property :last_name
property :full_name
end
end
end
PeopleRepresenter:
module Api
module V2
class PeopleRepresenter < Roar::Decorator
include Representable::JSON::Collection
self.representation_wrap = :people
items extend: Api::V2::PersonUnwrapRepresenter, class:Person
end
end
end
Api::V2::PeopleController:
module V2
class Api::V2::PeopleController < Api::V2::ApiController
include Roar::Rails::ControllerAdditions
include Roar::Rails::ControllerAdditions::Render
# GET /people
def index
p = Person.first # single model
# p = Person.find([8,18]) # collection model
render json:p
end
end
end
Maaan I didn't realize me you're using JSONAPI
- would have helped! :laughing:
Note that you need only ONE representer for both singular and collection. Please, check out if rendering works manually as documented here.
Then, we need to extend roar-rails to do the same. Rendering/parsing collection is not implemented, yet.
So the manual rendering worked! See my irb output below:
irb(main):006:0> Api::V2::PersonRepresenter.prepare(Person.first).to_json
Person Load (0.3ms) SELECT "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT 1
=> "{\"people\":{\"id\":\"dab4e5e6-ba50-42b4-9633-50a952d2e811\",\"first_name\":\"Chad\",\"last_name\":\"Taylor\",\"full_name\":\"Chad Taylor\"}}"
irb(main):008:0* Api::V2::PersonRepresenter.for_collection.prepare([Person.first, Person.last]).to_json
Person Load (0.5ms) SELECT "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT 1
Person Load (0.9ms) SELECT "people".* FROM "people" ORDER BY "people"."id" DESC LIMIT 1
=> "[{\"people\":{\"id\":\"dab4e5e6-ba50-42b4-9633-50a952d2e811\",\"first_name\":\"Chad\",\"last_name\":\"Taylor\",\"full_name\":\"Chad Taylor\"}},{\"people\":{\"id\":\"265abc1c-ef97-485b-b43d-13231108f4ab\",\"first_name\":\"\",\"last_name\":\"John Doe\",\"full_name\":\" John Doe\"}}]"
What do I need to do next? Extending roar-rails; how? Or is it something you need to do an update within the gem before it can function properly?
Ha of course manual rendering works! :stuck_out_tongue:
So far, roar-rails
doesn't know about the ::for_collection
method, we have to implement that. Do we have tests for JSONAPI, yet? Let me have a look.
Cool, let me know what I can do next if anything?
Check out this test: https://github.com/apotonick/roar-rails/blob/master/test/json_api_renderer_test.rb
You could add a test to render a collection here. This will fail, then we can easily fix it in roar-rails and people all over the world are gonna love you.
So this is the first time I have done a test (I know, I know, my peers have lectured me about that already).
Here's what I have:
require 'test_helper'
class HalRendererTest < ActionController::TestCase
include Roar::Rails::TestCase
class PeopleController < ActionController::Base
module JsonApiPersonRepresenter
include Roar::JSON::JSONAPI
type :people
property :first_name
end
include Roar::Rails::ControllerAdditions
represents :json_api, :entity => JsonApiPersonRepresenter
def show
person = Person.find 1
respond_with person
end
def index
people = Person.find([1,2])
respond_with people
end
end
tests PeopleController
test "should render single model correctly in response to a application/vnd.api+json" do
get :show, :id => "1", :format => :json_api
assert_body '{"people":{"first_name":"Chad"}}'
end
test "should have a content_type of application/vnd.api+json for a single model" do
get :show, :id => "bumi", :format => :json_api
assert_equal response.content_type, 'application/vnd.api+json'
end
test "should render collection of models correctly in response to a application/vnd.api+json" do
get :index, :format => :json_api
assert_body '{"people":[{"first_name":"Chad"},{"first_name":"Fremont"}]}'
end
test "should have a content_type of application/vnd.api+json for a collection of models" do
get :index, :format => :json_api
assert_equal response.content_type, 'application/vnd.api+json'
end
end
I have already added this to config/initializers/mime_types.rb:
ActionController::Renderers.add :json_api do |obj, options|
self.content_type ||= Mime[:json_api]
obj
end
Running the test gave us errors:
Finished in 0.077660s, 51.5066 runs/s, 0.0000 assertions/s.
1) Error:
HalRendererTest#test_should_have_a_content_type_of_application/vnd.api+json_for_a_collection_of_models:
NameError: uninitialized constant Mime::JSON_API
test/models/json_api_renderer_test.rb:24:in `index'
test/models/json_api_renderer_test.rb:47:in `block in <class:HalRendererTest>'
2) Error:
HalRendererTest#test_should_have_a_content_type_of_application/vnd.api+json_for_a_single_model:
NameError: uninitialized constant Mime::JSON_API
test/models/json_api_renderer_test.rb:19:in `show'
test/models/json_api_renderer_test.rb:37:in `block in <class:HalRendererTest>'
3) Error:
HalRendererTest#test_should_render_collection_of_models_correctly_in_response_to_a_application/vnd.api+json:
NameError: uninitialized constant Mime::JSON_API
test/models/json_api_renderer_test.rb:24:in `index'
test/models/json_api_renderer_test.rb:42:in `block in <class:HalRendererTest>'
4) Error:
HalRendererTest#test_should_render_single_model_correctly_in_response_to_a_application/vnd.api+json:
NameError: uninitialized constant Mime::JSON_API
test/models/json_api_renderer_test.rb:19:in `show'
test/models/json_api_renderer_test.rb:32:in `block in <class:HalRendererTest>'
4 runs, 0 assertions, 0 failures, 4 errors, 0 skips
Error seems to be around Mime; any ideas?
My bad, I forgot to add that line Mime::Type.register 'application/vnd.api+json', :json_api
to the mime_types.rb
file; oops!
Running the test, brb...
New test result with mime type fixed:
Finished in 0.110748s, 36.1180 runs/s, 9.0295 assertions/s.
1) Error:
HalRendererTest#test_should_have_a_content_type_of_application/vnd.api+json_for_a_collection_of_models:
NameError: uninitialized constant HalRendererTest::PeopleRepresenter
test/models/json_api_renderer_test.rb:24:in `index'
test/models/json_api_renderer_test.rb:47:in `block in <class:HalRendererTest>'
2) Error:
HalRendererTest#test_should_render_collection_of_models_correctly_in_response_to_a_application/vnd.api+json:
NameError: uninitialized constant HalRendererTest::PeopleRepresenter
test/models/json_api_renderer_test.rb:24:in `index'
test/models/json_api_renderer_test.rb:42:in `block in <class:HalRendererTest>'
3) Error:
HalRendererTest#test_should_render_single_model_correctly_in_response_to_a_application/vnd.api+json:
NoMethodError: undefined method `assert_body' for #<HalRendererTest:0x007fb7ab559028>
test/models/json_api_renderer_test.rb:33:in `block in <class:HalRendererTest>'
4 runs, 1 assertions, 0 failures, 3 errors, 0 skips
Sorry for bombing the thread here, I was able to fix the test and remembered you telling me about represent_items_with
couple of days ago:
Here's the new test results:
Finished in 0.115252s, 34.7066 runs/s, 17.3533 assertions/s.
1) Error:
HalRendererTest#test_should_render_collection_of_models_correctly_in_response_to_a_application/vnd.api+json:
NoMethodError: undefined method `assert_body' for #<HalRendererTest:0x007fd764db81c8>
test/models/json_api_renderer_test.rb:43:in `block in <class:HalRendererTest>'
2) Error:
HalRendererTest#test_should_render_single_model_correctly_in_response_to_a_application/vnd.api+json:
NoMethodError: undefined method `assert_body' for #<HalRendererTest:0x007fd764d2b458>
test/models/json_api_renderer_test.rb:33:in `block in <class:HalRendererTest>'
4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
The corrected test file:
require 'test_helper'
class HalRendererTest < ActionController::TestCase
include Roar::Rails::TestCase
class PeopleController < ActionController::Base
module PersonRepresenter
include Roar::JSON::JSONAPI
type :people
property :first_name
end
include Roar::Rails::ControllerAdditions
represents :json_api, :entity => PersonRepresenter
def show
person = Person.find 1
respond_with person
end
def index
people = Person.find([1,2])
respond_with people, represent_items_with:PersonRepresenter
end
end
tests PeopleController
test "should render single model correctly in response to a application/vnd.api+json" do
get :show, :id => "1", :format => :json_api
assert_body '{"people":{"first_name":"Chad"}}'
end
test "should have a content_type of application/vnd.api+json for a single model" do
get :show, :id => "bumi", :format => :json_api
assert_equal response.content_type, 'application/vnd.api+json'
end
test "should render collection of models correctly in response to a application/vnd.api+json" do
get :index, :format => :json_api
assert_body '{"people":[{"first_name":"Chad"},{"first_name":"Fremont"}]}'
end
test "should have a content_type of application/vnd.api+json for a collection of models" do
get :index, :format => :json_api
assert_equal response.content_type, 'application/vnd.api+json'
end
end
So it didn't look like it liked "assert_body" as was in the original test file you sent me. So I adjusted it:
test "should render single model correctly in response to a application/vnd.api+json" do
get :show, :id => "1", :format => :json_api
# assert_body '{"people":{"first_name":"Chad"}}'
assert_equal response.body, '{"people":{"first_name":"Chad"}}'
end
test "should render collection of models correctly in response to a application/vnd.api+json" do
get :index, :format => :json_api
# assert_body '{"people":[{"first_name":"Chad"},{"first_name":"Fremont"}]}'
assert_equal response.body, '{"people":[{"first_name":"Chad"},{"first_name":"Fremont"}]}'
end
And the new error is:
Finished in 0.113740s, 35.1679 runs/s, 35.1679 assertions/s.
1) Failure:
HalRendererTest#test_should_render_collection_of_models_correctly_in_response_to_a_application/vnd.api+json [/Users/chadwtaylor/Dropbox/web_projects/honey/linguabee-api/test/models/json_api_renderer_test.rb:46]:
--- expected
+++ actual
@@ -1 +1 @@
-"{\"people\"=>{\"first_name\"=>\"Chad\"}}{\"people\"=>{\"first_name\"=>\"Fremont\"}}"
+"{\"people\":[{\"first_name\":\"Chad\"},{\"first_name\":\"Fremont\"}]}"
4 runs, 4 assertions, 1 failures, 0 errors, 0 skips
I'm hoping that is the specific failure you wanted to see? :)
Any chance I could see a PR so I can diff? Thanks brother, legend!
Pardon my ignorance as I have never become a contributor for any projects -- so you wanted a PR on my test file?
Sent you a PR of my test; hoping I got this right...
Let me know what I can do for you. Would love to help!
Friendly reminder... I can only use render
as respond_with
throws a undefined method 'default_render'
error as discussed way above in this comment thread (am using the rails-api gem).
Friendly reminder: add test here: https://github.com/apotonick/roar-rails/blob/master/test/render_test.rb
Thanks for your help!
Everything worked great for a model. When it came to an array/collection of models, this is where I'm stuck and I wonder if it has to do with the fact my Rails API project is versioned (ie: v1, v2)?
The error message I'm getting when trying to load a collection:
uninitialized constant Api::V2::PeopleRepresenter
(and I already instructed the render to userepresent_items_with: Api::V2::PersonRepresenter
). I wonder if it has to do with modules/namespacing things?Here's what my set up looks like...
app/api/v2/api_controller
app/api/v2/people_controller
app/representers/api/v2/person_representer