How to connect Rails collection route to Ember JSON API Adapter? - ruby-on-rails

I have a Rails resource like this...
resources :listings do
collection do
get :stats
end
...
end
such that GETting /listings/stats?various_params gives me a JSON API compliant response with statistics about the Listing model according to the parameters I provide.
In my Ember frontend, also using the JSON API Adapter, I would like to be able to something like this:
model() {
return this.store.query('listing/stats', {startdate: startDate.toISOString, otherparams: etCetera});
}
What's the "Ember Way" to accomplish this, if any? I would like to avoid hacking the JSON API Adapter as much as possible, and it's my understanding that custom methods defined on an Ember model's file are mostly for interacting with a specific record (i.e., /listings/:id/whatever)
Thanks

I ended up using Mike North's ember-api-actions add on, which is working pretty well. If anyone has a short solution though, it would be welcome.

Related

What is the Best Practice for testing api controllers(active model serializers)?

I am working on an app and up to this point I have been testing just stuff like authentication and request response codes. but it seems like a good idea to test the structure of the payload. ie. if there is embedded resources or sidloaded resources. how do you guys test this. here is a sample of some of the testing I am doing. I am using active model serializers. but seems like a bit of cruft to organize.
describe '#index' do
it 'should return an array of email templates' do
template = EmailTemplate.new(name: 'new email template')
EmailTemplate.stub(:all).and_return([template])
get :index
payload = {:email_templates => [JSON.parse(response.body)["email_templates"][0].symbolize_keys]}
template_as_json_payload = {:email_templates => [ActiveModel::SerializableResource.new(template).as_json[:email_template] ]}
expect(payload).to eq(template_as_json_payload)
end
end
I'm fond of defining a schema for JSON responses and validating that any response seen in a test conforms to it. That alone does not guarantee that the values of the response are correct but it does tell you that the structure of the response matched your expectations.
Those schemas then become part of the documentation of the API which client implementations can reference. By using the schema in tests I get more confidence that the API documentation is not going to fall out of sync with the implementation. Making schema changes in order to get a passing test is also a good prompt for me to consider if a change is safe for existing API clients or if I need to release a new API version.
The folks at Thoughtbot have a nice example of validating schemas using rspec: https://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher
This is one way to do it:
body = JSON.parse(response.body)
assert_equal(body.keys, ["id", "author"])
assert_equal(body["author"].keys, ["id", "name"])
But you should checkout the link that Jonah shared, it's worth reading.

How can I access my Rails backend API information in my Ember client side?

I'm a beginner at coding and I'm working on this tutorial right now and I'm having a bit of trouble. I would really appreciate some help!
Here's my problem: I'm using an external API in my Rails backend. I'm not using a model. But the tutorial is asking me to access a model in this section when I want to access my API information from my Rails class.
This is what they want me to do:
Library.BooksRoute = Ember.Route.extend({
model: function() {
return this.get('store').find('book');
}
});
How can I change that code to access my API? I'm using HTTP party.
Here's a bit of what my activities controller looks like:
class BooksController < ApplicationController
respond_to :json
include HTTParty
base_uri '' # took this out
def index
render json: self.class.get("") # took out my link with API key here
end
end
Thanks in advance!
that ember code looks correct. I think part of the confusion is that Ember has its own models which are not the same as rails models.
The tutorial asks you to curl your books endpoint. Have you verified you can do that and are getting back an JSON object representing your books?
If you're getting back valid JSON and ember is set up to use the ActiveModelAdapter (like the tutorial says ember-rails automatically does for you) then this.store.find('book') in the model route should make a GET request to your rails API book endpoint. You can perform a network trace in chrome developer tools to verify this.
What evidence do you have that this is not working?

How to create a scaffold with differing controller and model names?

I'm making a versioned JSON API in rails, where the controllers also respond to HTML, meaning it can be accessed as a browser or through an app I'm developing. The controllers have the form Model::V1::UsersController (Model instead of API since they don't just respond to JSON), and I currently have the following in my routes.rb:
namespace :model, path: 'm', as: '' do
# For objects in the model, accessible by JSON (through the app) or HTML (through the browser, using forms to send data to the server).
scope module: 'v1', constraints: OrConstraint.new([APIConstraint.new(1), APIConstraint.new(:default)]) do
resources :users do
collection do
post :sign_in
end
end
end
end
I plan to add more models to my API, but how can I use scaffolding to do this? For example, to create a controller Model::V1::CommentsController, but using the Comment model, instead of Model::V1::Comments.
I've been trying to figure this out for hours, and googling for people with similar problems shows that a few people say not to use scaffolding at all in this case: I don't want to do this, as it would mean writing all the views myself, which would be very time-consuming. Apart from that, I can't find much. nifty-generators was suggested somewhere, but it doesn't seem to be maintained anymore: no activity since 2012. I'm new to rails, and it might be that I've missed something quite obvious, but I find it surprising that not many others have had the same issue.
I've considered making my own generator, but looking at the source of https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb, it seems very complicated.
EDIT: I've just discovered that I can pass the --model-name parameter to the rails scaffold generator to achieve what I want, but for some reason it still tries to create a model with the same name as the controller. How can I change this?
I've settled with this solution, by not generating a model at all using the scaffold generator:
To create Model::V1::CommentsController as the controller and Comments as the model:
rails g model comment
rails g scaffold model/v1/comments --model-name=comment --no-orm

Finding sets in Rails

I'm a Rails noob, but I'd like to use it as a backend for an Ember application with Ember Data. Unfortunately, I have some unknown unknowns.
The RESTAdapter documentation says:
Comments for a post can be loaded by post.get('comments'). The REST
adapter will send a GET request to /comments?ids[]=1&ids[]=2&ids[]=3.
It will generate similar urls if you use something like App.Post.find({title: "Some Title"}), in about the format you'd expect: /posts?title=Some+Title
Is there some option, or gem I can use to handle that sort of simple query, or do I have to go parse parameters in my controllers manually?
To clarify, I'm aware that I can tell my Rails controller to return a set like:
#comments = Comment.find(params[:ids])
respond_with(#comments)
But it seems like querying on ids or accessible attributes like that would be a common enough use case for REST APIs that something would be built in, or have a gem written to handle it.
Can anyone point me in the right direction?
Thanks.
This might be helpful in your case:
https://github.com/ernie/ransack/
Or
https://github.com/ernie/squeel

Rails Creating a json only api and routes

I'm adding an api to an existing application.
I created a controller "api" and am using rabl to handle my views and return json.
Ideally I want the routes to be something like this: (We have a User controller and model set up).
/api/users/show.json?id=1 etc...
I have the api/index.json working and returning my rabl template, but I can't seem to get the /api/users/show.json to do anything
I set this up:
scope "/api" do
resources :users
end
But that redirects from "/api/users" to "/users/new"
I'd like to keep everything in the api section to itself, and not have to mix up my rabl templates within the views/users or in the users controller.
Thanks for any light you might be able to shed on this.
Im not sure if i got your problem, but i think your route may be wrong.
It should be something like
/api/users/1.json

Resources