Im trying to create simple Ruby on Rails REST API.
app/controllers/api/vi/product_controller.rb
module Api
module V1
class ProductController < ApplicationController::API
def index
render json: {message: 'Welcome!'}
end
end
end
end
config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get '/product', to: 'product_controller#index', as: 'product'
end
end
end
When I run project on localhost, I get uninitialized constant Api::V1::ApplicationController routing error. Can anyone help to such Ruby on Rails newbie as I am?
you just need to create a folder inside controllers called api and a v1 folder inside api.
You should provide all the controllers inside v1 folder.
In your app/controllers/api/v1/product_controller.rb
class Api::V1::ProductController < ApplicationController
def index
render json: {message: 'Welcome!'}
end
end
In your routes:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get '/product', to: 'product_controller#index', as: 'product'
end
end
end
you nested the route, so it should be '/api/v1/product`
if you run rake routes from your console, you will get a list of all available routes.
for more information about routing and nested routes, have a look at rails guides
change this and try:
module Api
module V1
class ProductController < ApplicationController
def index
render json: {message: 'Welcome!'}
end
end
end
end
Related
I'm trying to create the below route but I am running into a "routing error" of "uninitialized constant Foo::Bar::Biz"
/foo/bar/biz/<biz_id>/custom
My routes file is as follows:
namespace(:foo) do
namespace(:bar) do
resources(:biz, only: []) do
get('/custom' => 'foo/bar/biz/custom#index') # I have also tried just custom#index
end
end
end
When I run rake routes I see the route and the controller.
/foo/bar/biz/:biz_id/custom(.:format) foo/bar/biz/custom#index
My controllers file structure is this:
controllers/foo/bar/biz/custom_controller.rb
I don't currently have a controller for biz, but I have tested with one present.
My custom_controller is as follows:
module Foo
module Bar
module Biz
class CustomController < FooController
def index
// do something
end
end
end
end
end
I suspect my routes are setup correctly and my error is in my controller or module setup. Is there something I am missing?
Change your path
'foo/bar/biz/custom#index'
to path starting with root (/)
namespace(:foo) do
namespace(:bar) do
resources(:biz, only: []) do
get('/custom' => '/foo/bar/biz/custom#index')
end
end
end
I have created API in rails 5.
I am getting error superclass mismatch for class UsersController.
My controller:
module Api
module V1
class UsersController < ApplicationController
def index
users = User.Order('created_at DESC')
render json: {status:"SUCCESS", message:"Load Users", data:users}, status: :ok
end
def create
user = User.new(user_params)
end
def user_params
params.permit(:firstname, :lastname, :email, :age, :id)
end
end
end
end
My routes:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users
end
end
end
Here is my folder structure:
I got below error in console:
Actually, I have just started in ruby on rails. I tried to figure out problem but couldn't find it.
You need to reference ApplicationController from the Main module (the "global" namespace in Ruby):
module Api
module V1
class UsersController < ::ApplicationController
:: tells Ruby to resolve the constant from main rather than the current module nesting which is Api::V1.
You also need to ensure that ApplicationController inherits from ActionController::API.
See:
Everything you ever wanted to know about constant lookup in Ruby
Similar to this question but the answers there don't work here.
In routes.rb
scope '/api/ do
namespace :v1 do
scope :reports do
get '/reportXYZ', to: 'reports#reportXYZ'
end
end
end
In app/controllers/V1/reports_controller.rb
module V1
class ReportsController < ApplicationController
def reportXYZ
...
end
end
end
the error:
uninitialized constant V1 on Windows only, works fine on ubuntu. How come?
In your routes .rb file instead of writing scope for api write like this
namespace :api do
namespace :v1 do
scope :reports do
get '/reportXYZ', to: 'reports#reportXYZ
end
end
end
And in your controller
module api
module V1
class ReportsController < ApplicationController
def reportXYZ
...
end
end
end
END
I'm trying to setup a RoR API but I'm hitting a few roadbump along the way. After tiresome coding to get the database setup right I'm hitting an error that doesn't quite make sense to me (I'm new to RoR)
Unable to autoload constant Api::V1::SubmissionsController, expected ./app/controllers/api/v1/submissions_controller.rb to define it
I'm not quite sure what this error means and my interwebs searches are coming up empty on a clear answer. I'm hoping any of you can help me here.
Routes
Rails.application.routes.draw do
namespace :api, :defaults => {:format => :json} do
namespace :v1 do
get "/submissions", to: "submissions#index"
end
end
end
submission.rb
class Submission < ActiveRecord::Base
end
submissions_controller.rb
class API::V1::SubmissionsController < ApplicationController
def index
#submissions = Submission.all
render json: #submissions, status: :ok
end
end
Your file contains:
class API::V1::SubmissionsController < ApplicationController
Rails expects:
class Api::V1::SubmissionsController < ApplicationController
What does your folder structure look like for app/controllers & app/views? Depending on how these files were generated, by "rails generate" or manually created, if you namespace, the folder structure has to match in controllers and views directories.
app/controllers/api/v1
app/views/api/v1
I have two API controllers in my Rails app for a RESTful setup:
StoresController (has many products)
ProductsController (has one store)
How can I write the API so that
http://localhost:3000/api/v1/stores/37/products
returns only the products for that store(in this case store #37)? I think I'm missing a route and controller method to make that happen.
Routes
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :stores
resources :licenses
end
end
API Controllers
APIController:
module Api
module V1
class ApiController < ApplicationController
respond_to :json
before_filter :restrict_access
private
def restrict_access
api_app = ApiApp.find_by_access_token(params[:access_token])
head :unauthorized unless api_app
end
end
end
end
StoresController:
module Api
module V1
class StoresController < ApiController
def index
respond_with Store.all
end
def show
respond_with Store.find_by_id(params[:id])
end
end
end
end
ProductsController:
module Api
module V1
class ProductsController < ApiController
def index
respond_with Product.all
end
def show
respond_with Product.find_by_id(params[:id])
end
end
end
end
Thanks for any insight.
You want nested resources in your routes:
resources :stores do
resources :products
end
So you have those routes:
GET /stores/:id
GET/POST /stores/:store_id/products
PUT/DELETE /stores/:store_id/products/:id
You'll may also want shallow routes, to avoid deeply nested resources:
resources :stores, shallow:true do
resources :products
end
So you have those routes:
GET /stores/:id
GET/POST /stores/:store_id/products
PUT/DELETE /products/:id
Once you have the routes, you may just first load the parent store, and use the products association:
#store = Store.find(params[:store_id])
#products = store.products
You can scope the products by the store id.
class ProductsController < ApiController
def index
store = Store.find(params[:store_id])
respond_with store.products
end
end
If you look at your route:
http://localhost:3000/api/v1/stores/37/products
You'll find that 37 is part of your route provided in your params, probably in :store_id. Check rake routes to be sure.