I'm using ember with ember-data. The initial request for a resource index (api/v1/facilities) works fine. Then ember requests the has_many relations (api/v1/facilities/195/jobs) and rails 404s.
This is I guess just a development problem, as I'm running ember server on localhost:4200, with rails on :3000. But I don't want to give up the ember server side :P
I remember hitting the CORS thing when I started the project, but it's a part-time thing, and it was a while ago. Somehow I got it working (I think I just commented out protect_from_forgery in application_controller.rb). I deviated from the Readme by creating an (empty) ResourcesController that inherits from JSONAPI::ResourceController, which my FacilitiesController, JobsController, etc inherit from.
Here's my routes file:
#config/routes.rb
namespace :api, constraints: { format: 'json' } do
namespace :v1 do
jsonapi_resources :facilities, except: [:new, :edit] do
jsonapi_related_resources :jobs
end
jsonapi_resources :providers, except: [:new, :edit]
jsonapi_resources :jobs, except: [:new, :edit]
end
end
Not sure what else to write, I don't know why the initial request for the parent resource succeeds while the nested resource fails. Thanks for your time, help a newb out? :)
I'm guessing that there are two separate issues here.
404'd
First, what does it say when you run rake routes? My rake routes doesn't have any OPTIONS-based routes, so that might be a manual addition. A quick skim through the controller tests suggests that the HTTP method OPTIONS isn't baked into JR. (Someone please correct me if I'm wrong.)
CORS
Do you have Rack::Cors (gem 'rack-cors', require: 'rack/cors') or any other CORS-related configuration set up in your application? That would be necessary to allow OPTIONS requests through.
As far as CORS requests in your development environment go, you can use the rack-cors gem and include a snippet like this in your config/environments/development.rb:
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins 'localhost:4200', '127.0.0.1:4200'
resource '*', :headers => :any, :methods => [ :options ]
end
end
This allows OPTIONS requests from port 4200 on localhost for any kind of resource and will prevent your server from blowing up in development.
Thanks very muchly. Still don鈥檛 understand why the first requests were going through, but everything鈥檚 working right now. ;)
@byelipk Do you need to add a catch-all route for OPTIONS in config/routes.rb as well?
@jeffbonhag
I do not believe that is necessary. In the snippet above it shows that Rack::Cors middleware prepends itself before ActionDispatch - which handles Rails routing - with config.middleware.insert_before 0
What this means is that Rack::Cors will get the first shot at filtering cross origin requests. I am not sure what it does with the request after it intercepts it.
Here is the ruby gem:
https://github.com/cyu/rack-cors
@clov3rly
I'm not sure why either. But I have an idea. When jsonapi-resources adds the urls in a links field the domain of that url is going to be that of your rails server.
"links": {
"self": "http://localhost:3000/posts",
}
If you develop your ember app using ember-cli, you're probably going to be developing on localhost:4200. These are different origins.
If ember data sees that your posts are at localhost:3000/posts it is going to make that cross origin request. If you proxy your requests while developing your ember app to localhost:3000, somewhere the proxy server is noticing you want to make a cross origin request and it will attempt to do so.
Just an idea.
@byelipk, thanks for your help. 聽I got it sorted out.
@clov3rly did you work out why it was requesting the options route and how to solve that? I'm currently bumping into this also.
For those that find this issue in the future and are working with Rails/JSONAPI-Resources/Ember Data:
I fixed this by adding the the :patch option to the Rack::Cors application.rb config under the methods option. With the common copy/pasta implementation that Rack::Cors provides, you're able to save new records, but when ED goes to update an existing record it sends an OPTIONS request with the Access-Control-Request-Method:PATCH header. This requires the :patch option for it to work.
Thanks @Gowiem, adding patch solved the problem!
Most helpful comment
For those that find this issue in the future and are working with Rails/JSONAPI-Resources/Ember Data:
I fixed this by adding the the
:patchoption to theRack::Corsapplication.rbconfig under themethodsoption. With the common copy/pasta implementation thatRack::Corsprovides, you're able to save new records, but when ED goes to update an existing record it sends anOPTIONSrequest with theAccess-Control-Request-Method:PATCHheader. This requires the:patchoption for it to work.