uninitialized constant Api::Doorkeeper - ruby-on-rails-4

I have API engine inside my Rails app and I've mounted the engine under in the main app routes
Rails.application.routes.draw do
mount Api::Engine => "/api"
end
and I want to add the doorkeeper routes using use_doorkeeper function in my routes like this
Api::Engine.routes.draw do
use_doorkeeper :scope => "api/oauth"
end
this doesn't work because it tries to find controllers under api/doorkeeper/controller_name instead of doorkeeper/controller_name
as a workaround I've added doorkeeper routes in main app routes.rb with a scope like this
Rails.application.routes.draw do
mount Api::Engine => "/api"
use_doorkeeper :scope => "api/oauth"
end
But I want to know if there is a solution so I can still add the routes to api/config/routes.rb and make reference the correct controllers path

my colleague suggested this solution found here and it worked for me :)
MyEngine::Engine.routes.draw do
old_scope = #scope[:module]
#scope[:module] = nil
use_doorkeeper
#scope[:module] = old_scope
end

Related

Customize resource routing in Rails 4

think of the resource routing of a photo-class for example.
If I this to my routes.rb I will get following routes:
resources :photos
# GET '/photos/', :to => 'photos#index'
# GET '/photos/:photo_id/, :to => 'photos#show'
# and so on and so on
Now what I want is to replace the word /photos in all the routes with a simple /p so that I can get a short URL like /p/1 for the first photo. Is there a way to simply alter the resource-line or do I have to manually add each route?
This will make all your routes via :photos through p
resources :p, :controller => "photos"
To be more concise and avoid the issue with p_id, you could do it like this :
resources :photos, path: 'p'
This way, you benefits from the readibility on your end (it will generate helpers like edit_photo_path, you will access variables as photo_id in case of a nested route and such) and generate the named URLs you do want.

Ruby on Rails App Testing with Rspec and Capybara

when i create a feature test for my application get the following error:
ActionController::RoutingError:
No route matches [GET] "/example"
My application uses subdomains and sub-applications(engines/modules) within these subdomains. Now when i set for Capybara the app_host or default_host through an feature_subdomain_helper like
Capybara.app_host = "example.lvh.me" or
Capybara.default_host = "example.lvh.me"
and into my rails_helper.rb i add the following code line
config.extend SubdomainHelpers, type: :feature
I get the same error. Now i think the configured subdomain are not considered by my feature test.
My Rspec Version is: 3.2
and Capybara Version is: 2.4.4
My sample feature test looks like:
require 'rails_helper'
feature 'Example Page' do
scenario 'visit example page' do
visit "/example"
expect(page).to have_content 'Example'
end
end
Have someone an idea what i do wrong?
Edit:
Mainapp routes:
constraints(Subdomain) do
mount Example::Engine => '/', as: 'example'
end
Engine routes:
Example::Engine.routes.draw do
scope '/example', nav_scope: 'example' do
end
end
The names of Capybara.default_host and Capybara.app_host are slightly misleading since they both need to be set as URLs to function properly
Capybara.default_host = "http://example.lvh.me"
If that doesn't fix your issue check rake routes and make sure the action you think is mounted at '/example' really is.

Rails: aliasing the index action in the routes file

I have the following route set up. I need to make the index action automatically use the pubmed_search route below.
resources :users do
resources :publications do
collection do
get :pubmed_search
post :pubmed_list
end
end
end
I tried
resources :users do
resources :publications do
collection do
get 'publications', :action => :pubmed_search
get :pubmed_search
post :pubmed_list
end
end
end
Without luck I could just do a redirect in the index method of the controller but i am sure there is a Rails way to do this and I want to learn.
EDIT:
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"
But isn't there a better way, using the RESTful resources?
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"

Rails Domain Constraints ( to serve multiple domains )

$ rails -v Rails 4.2.1
$ ruby -v ruby 2.2.2p95 (2015-04-13 revision > 50295) [x86_64-linux]
I am building an API for a mobile app, which will have an admin interface to it. What i'm attempting to do, is run this through nginx using unicorn ( which I have running on my dev environment)
I have 2 domains routed to the exact same rails project. These domains are: api.project.dev and admin.api.project.dev
I've read this:
http://guides.rubyonrails.org/routing.html#advanced-constraints
and tried:
Separate Domain for Namespaced Routes in Rails 4 ( see answer )
I've tried a few other things to try and get this to work, the only thing that comes up ( for either sub-domain ) is:
Invalid route name, already in use: 'root'
My current implementation of this is:
class DomainConstraint
def initialize(domain)
#domains = domain
end
def matches?(request)
#domains.include? request.domain
end
end
and
require 'domain_constraint'
Rails.application.routes.draw do
resources :statuses
constraints (DomainConstraint.new('api.project.dev')) do
root :to => 'statuses#index'
end
constraints(DomainConstraint.new('admin.api.project.dev')) do
root :to => 'statuses#new'
end
end
keep in mind that the roots are different pages only for now, but ultimately will be completely different systems.
Not quite sure where to go from here in order to get this functioning as I would hope.
With the fine help of the great people in #RubyOnRails on irc I got this figured out. So thanks crankharder and sevenseacat for your input and advice.
What I ended up with was this:
class DomainConstraint
def initialize(domain)
#domains = domain
end
def matches?(request)
#domains.include? request.host
end
end
and:
require 'domain_constraint'
Rails.application.routes.draw do
constraints DomainConstraint.new('api.project.dev') do
resources :statuses
root :to => 'statuses#index', as: 'api_root'
end
constraints DomainConstraint.new('admin.api.project.dev') do
resources :statuses
root :to => 'statuses#new'
end
end
You can also constrain a route based on any method on the Request object that returns a String. http://guides.rubyonrails.org/routing.html#request-based-constraints
The methods available to Request include host, which could be used as follows:
constraints host: 'api.project.dev' do
resources :statuses
root to: 'statuses#index', as: 'api_root'
end
constraints host: 'admin.api.project.dev' do
resources :statuses
root to: 'statuses#new'
end

Devise+Omniauth, routes versioning

I have a model Candidate which is devise omniauthable (linkedin).
So far, my routes.rb looked like this :
namespace :v1 do
devise_for :candidates, only: :omniauth_callbacks
...
end
Everything worked well till I had to add a new version :
namespace :v2 do
devise_for :candidates, only: :omniauth_callbacks
...
end
namespace :v1 do
devise_for :candidates, only: :omniauth_callbacks
...
end
With the current configuration, I get this error :
`set_omniauth_path_prefix!': Wrong OmniAuth configuration. If you are getting this exception, it means that either: (RuntimeError)
1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one
2) You are setting :omniauthable in more than one model
3) You changed your Devise routes/OmniAuth setting and haven't restarted your server
It's kind of annoying since I want to be able to authenticate the candidate on both versions.
What can I do ?
Alright, let's recap a little bit here, Devise doesn't allow you to call the devise_for method inside a scope or a namespace route defined in the config/routes.rb file, right?
My namespace'd route looks like this:
namespace :api, constraints: { format: :json } do
devise_for :users, skip: [ :registrations, :passwords, :confirmations ]
resources :profiles, only: :show
end
And it works!
What did I do to make it work? the answer lies in the config/initializers/devise.rb file.
Check out near the bottom of the File it says...
# When using omniauth, Devise cannot automatically set Omniauth path,
# so you need to do it manually. For the users scope, it would be:
The next commented line shows you an example, uncomment that line and modify it according to your needs, for my case(ie. for the namespaced route I have above) I have:
config.omniauth_path_prefix = "/api/users/auth"
And that's it! .... I did that and it all started to work perfectly!
Hope it helps!