-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Versioning and Roar #106
Comments
Have you looked into the |
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: I'm hoping I can create one PersonRepresenter that will deal with collections as well, hence the Thanks for your invaluable help! |
I'm still wondering, though, why the |
What else do you need to see from my end to narrow down the issue? |
I even tried to change from
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 |
I switched to
The only thing working for me is using # 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 |
|
(want to say how much I appreciate your help here!) |
"No worries, mate!" as they say in Australia! 😉 This is your problem: 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
|
I hate Rails. |
What roar-rails version are you on? |
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! 😜 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 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! 😛 |
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 Wait, what was your actual problem in the first place? We can make that work and you keep using |
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 I even created a I wonder though if the |
It sounds like your representers for singular models are ok. However, you need to define a representer for collections, too (or use |
Do you have a sample of what a representer for collections should look like? Yea, |
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:
I would think it should look like this...
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 |
Ah, thanks... just added
|
Haha, no, I am saying |
(will paste soon; BTW just bought your book....) |
I commented out However, I need to keep Here's the 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
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:
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 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:
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! 😛 So far, |
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:
Error seems to be around Mime; any ideas? |
My bad, I forgot to add that line Running the test, brb... |
New test result with mime type fixed:
|
Sorry for bombing the thread here, I was able to fix the test and remembered you telling me about Here's the new test results:
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:
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 |
Friendly reminder: add test here: https://github.com/apotonick/roar-rails/blob/master/test/render_test.rb Thanks for your help! |
On it right now. This one is for JSON. I will create another test for JSONAPI. |
You don't have to create a test for JSONAPI and |
Just sent you a PR. The reason I wanted to do a JSONAPI test when using |
Ah yeah, that's true, so in |
Will send you another PR in a bit. |
Awesome, my first contributions! :) So, as you can see, the use of Instead, I am currently using Do you think we will see that day? I really, really hope so.... begging, begging |
It's bed time here for me on this side of earth. :) So if there's anything else you'd like me to do, feel free to holler! Would love to know your thoughts on a rails-api utilizing JSON and respond_with, would that be possible? |
Absolutely, let's make the |
hey @apotonick, where does making I'd be happy to pick up where ya'll left off if you fill me in. |
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
The text was updated successfully, but these errors were encountered: