I\'m pretty new to ruby, coming from a php background, but something is not clicking with me.
So, let\'s say I have a Ruby on Rails application and I am versioning m
You should check the guide to understand the routing: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
I think this question is very similar to:
Rails Controller Namespace
And as shortage:
Rails will detect the namespace automagically by the folder. So you don't need to append it to the name:
This blog post explains it so well:
http://blog.makandra.com/2014/12/organizing-large-rails-projects-with-namespaces/
Let's say we have an Invoice class and each invoice can have multiple invoice items:
class Invoice < ActiveRecord::Base has_many :items end class Item < ActiveRecord::Base belongs_to :invoice endClearly Invoice is a composition of Items and an Item cannot live without a containing Invoice. Other classes will probably interact with Invoice and not with Item. So let's get Item out of the way by nesting it into the Invoice namespace. This involves renaming the class to Invoice::Item and moving the source file to app/models/invoice/item.rb:
class Invoice::Item < ActiveRecord::Base belongs_to :invoice end
Same is applied to controllers and views.
When you use
#The code in question
module Api
module V1
class UserController < ApplicationController
end
end
end
ApplicationControllerdefinition will be searched in Api::V1 then if not found in Api then if not found in the root namespace.
I agree it could be confusing, that's why I tend to use absolute paths like so: ::ApplicationController
If ever I'd need Api::ApplicationController, I'd write ::Api::ApplicationController
Basically the :: tells ruby to start from the root namespace and not from where the code lives.
Sidenote
Be aware that there are vicious cases in Rails development mode. In order to gain speed, the strict minimum is loaded. Then Rails looks for classes definitions when needed.
But this sometimes fails big time example, when you have say ::User already loaded, and then look for ::Admin::User. Rails would not look for it, it will think ::User does the trick.
This can be solved using require_dependency statements in your code. Speed has a cost :)
I would rather suggest don't write ApplicationController in namespace, I would suggest to follow following
Note: If you are building professional api's it always good to have Api::V1::BaseController inheriting from ActionController::Base, though I am giving solution to your specific case
Ref this post: Implementing Rails APIs like a professional
1) Define application controller in usual way in app/controllers/application_controller.rb as
class ApplicationController < ActionController::Base
end
2) Define base api controller namely Api::V1::BaseController in app/controllers/api/v1/base_controller.rb which will inherit from ApplicationController (your case) like
class Api::V1::BaseController < ApplicationController
end
3) Define your api controllers like Api::V1::UsersController in app/controllers/api/v1/users_controller.rb which will inherit from Api::V1::BaseController
class Api::V1::UsersController < Api::V1::BaseController
end
4) Add all subsequent controllers like Api::V1::UsersController (step 3)
Then routing will contain namespaces routing in config/routes.rb
namespace :api do
namespace :v1 do
resources :users do
#user routes goes here
end
# any new resource routing goes here
# resources :new_resource do
# end
end
end