I would like to use a controller with EC module like EC::HomeController.
# app/cotrollers/ec/home_controller.rb
class EC::HomeController < ApplicationController
def index
end
end
It works in rails console.
[1] pry(main)> EC::HomeController
=> EC::HomeController
But in routes.rb it doesn't work...
# config/routes.rb
Rails.application.routes.draw do
namespace :ec do
namespace :home do
get "/" => :index
end
end
end
And access to http://localhost:3000/ec/home, then get
LoadError in Ec::HomeController#index
Unable to autoload constant Ec::HomeController, expected
/Users/wadako/coincheck/app/controllers/ec/home_controller.rb to define it
It loads Ec::HomeController not EC::HomeController.
Can't I use capital module name for rails4 routes?
in config/initializers create inflections.rb. In this file define:
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'EC'
end
This will allow you to use your module name in caps.
Lets work on that routes.rb!
Rails.application.routes.draw do
resources :home, only: :index, module: 'EC'
end
This should give you a route helper home_path that maps to EC:HomeController#index
Related
I have the following code
application.rb
config.autoload_paths += %W(#{config.root}/config/routes)
routes.rb
Rails.application.routes.draw do
root to: 'summary#index'
extend General
end
/config/routes/general.rb
module General
def self.extended(router)
router.instance_exec do
# devise routes
devise_for :users, controllers: { sessions: 'users/sessions' }
end
end
end
I get uninitialized constant General when loading the app.
I''m using Ruby 2.2.6 and Rails 5.0.2
in rails 6, you can use draw(:general), which will look for route definition in config/routes/general.rb
You can emulate this with an initializer:
module RoutesSubfolder
# Extension to Rails routes mapper to provide the ability to draw routes
# present in a subfolder
#
# Another solution would be to add the files to `config.paths['config/routes']`
# but this solution guarantees the routes order
#
# Example: <config/routes.rb>
#
# Rails.application.routes.draw do
# # this will eval the file config/routes/api.rb
# draw :api
#
# Example:
# draw :'api/whatever' # loads config/routes/api/whatever.rb
#
def draw(name)
path = Rails.root.join('config', 'routes', "#{name}.rb")
unless File.exist?(path)
raise StandardError, "Unable to draw routes from non-existing file #{path}"
end
instance_eval(File.read(path), path.to_s, 1)
end
end
ActionDispatch::Routing::Mapper.prepend(RoutesSubfolder)
The only difference with what you proposed is that:
you don't need to change the autoload_path
in general.rb, you directly declare your routes the same way you'd do in config/routes.rb inside the Rails.application.routes.draw do block
I'm getting this error.When I want to run te server on localhost:3000/api/v1/songs.json
Routing Error
uninitialized constant API::V1::SongsController.
Thats my routes.rb file:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :songs, only: [:index, :create, :update, :destroy]
end
end # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Routes
Routes match in priority from top to bottom
Helper HTTP Verb Path Controller#Action
Path / Url
Path Match
api_v1_songs_path GET /api/v1/songs(.:format)
api/v1/songs#index
POST /api/v1/songs(.:format)
api/v1/songs#create
api_v1_song_path PATCH /api/v1/songs/:id(.:format)
api/v1/songs#update
PUT /api/v1/songs/:id(.:format)
api/v1/songs#update
DELETE /api/v1/songs/:id(.:format)
api/v1/songs#destroy
and thats my SongsController:
class Api::V1::SongsController < Api::V1::BaseController
def index
respond_with Song.all
end
def create
respond_with :api, :v1, Song.create(song_params)
end
def destroy
respond_with Song.destroy(params[:id])
end
def update
song = Song.find(params["id"])
song.update_attributes(song_params)
respond_with song, json: song
end
private
def song_params
params.require(:song).permit(:id, :name, :singer_name, :genre, :updated_at, :tag)
end
end
I'm going to copy how we have this running, cause I cannot see a direct difference between your code and our code....
routes.rb
constraints subdomain: Settings.subdomains.api do # you can ignore this
namespace :api do
namespace :v1 do
resources :maps, only: [] do
collection do
get :world_map
end
end
end
end
maps_controller.rb
module Api
module V1
class MapsController < BaseController
def world_map; end
end
end
end
routes output
world_map_api_v1_maps GET /v1/maps/world_map(.:format) api/v1/maps#world_map {:subdomain=>"api"}
The spelling is really crucial from what I can see.
The directort structure for us:
app/controllers/api/v1/maps_controller.rb
So check those points and this should work because it's standard Rails magic.
Attempting to create an API using doorkeeper. When I sign into my account and the session user is authenticated and access my API on
http://localhost:3000/api/v1/trials
I get a routing error page saying "uninitialized constant TrialsController" and a rake routes listing. Including:
trials_path GET /api/v1/trials(.:format) trials#index
I am using rails version 4.0.3, ruby 2.0.0. This is my config/routes.rb file:
MyApp::Application.routes.draw do
devise_for :users
use_doorkeeper :scope => 'oauth2' do
end
root :to => 'welcome#index'
scope 'api' do
scope 'v1' do
resources :trials
end
end
end
My app/ dir contains:
app/
controllers/
application_controller.rb
welcome_controller.rb
api/
v1/
trials_controller.rb
My trials_controller.rb is:
module Api::V1
class TrialsController < ::ApplicationController
doorkeeper_for :all
def index
#trials = Trials.all
end
def show
...
end
...
end
end
UPDATE:
When I change the routes.rb to namespace the trails controller like so:
namespace :api do
namespace :v1 do
resources :trails
end
end
I get a "no route matches" error when attempting to access:
http://localhost:3000/api/v1/trials(.json)
(With or without the extension.)
I have also added to trials#index:
def index
#trials = Trials.all
respond_to do |format|
format.json { render :json => #trials }
format.xml { render :xml => #trials }
end
end
Also with no luck.
I'm not sure how it would play out against doorkeeper but I have a similar API structure in an app. I have the following in my routes (matching what Sergio notes)
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :api_controller_1
resources :api_controller_2
end
end
And here's how I build my API classes:
module Api
module V1
class ApiNamedController < ApplicationController
# code
end
end
end
Here is my code
namespace :appname do
resources :docs do
collection do
get 'contact'
get 'how_it_works'
get 'terms'
get 'privacy'
end
end
end
It generates
/appname/docs/contact
/appname/docs/how_it_works
/appname/docs/privacy
/appname/docs/terms
But how to make them as
/docs/contact
/docs/how_it_works
/docs/privacy
/docs/terms
my controller code
class Appname::DocsController < ApplicationController
def how_it_works
end
def privacy
end
def contact
end
def terms
end
end
defined the routes as follow
scope module: 'appname' do
resources :docs do
collection do
get 'contact'
get 'how_it_works'
get 'terms'
get 'privacy'
end
end
end
you can get more info from the rails routing guide in the namespace section. http://guides.ruby-china.org/routing.html
Remove the outer namespace :appname ... end block.
I am trying to use namespaces to declare an api.
My routes.rb contains:
devise_scope :user do
namespace :api do
namespace :v1 do
match 'log_in', :to => 'token_authentications#log_in', :via => "post"
end
end
end
And my *token_authentications_controller.rb* looks like this:
class Api::V1::TokenAuthenticationsController < ApplicationController
...
def log_in
...
end
...
end
When I hit: api/v1/log_in I get:
Routing Error
uninitialized constant Api
So do I need to declare the namespace somewhere?
Rails expects namespaces to follow directory structure, unless I'm mistaken.
Given your class name for your controller, Api::V1::TokenAuthenticationsController, rails expects it to live in app/controllers/api/v1/token_authentications_controller.rb.
If you just move your controller to the correct folder, I think you should be fine.
You might also want to make sure to actually declare the namespace modules somewhere, like for instance refactoring your controller as such:
module Api
module V1
class TokenAuthenticationsController
...
end
end
end