I am building a rails API, and I want to see the data in my browser when I use the appropriate url followed by .json or .xml. I am getting the following error:
Circular dependency detected while autoloading constant Api::V1::VersionsController
I set up a versions_controller.rb in the path music-app/app/controllers/api/v1/versions_controller.rb:
class API::V1::VersionsController < ApplicationController
respond_to :json, :xml
def index
#versions = Version.all
respond_with(#versions)
end
def show
#versions = Song.find_by(:id => params[:song_id]).versions
respond_with(#versions)
end
end
and my routes:
namespace :api do
namespace :v1 do
get '/versions' => 'versions#index'
get '/versions/:id' => 'versions#show'
end
end
Am I missing something, and how can this be resolved?
It seems to be the uppercase of API in the controller that is causing your issues.
Try capitalized
class Api::V1::VersionsController < ApplicationController
Related
I have created a rails project that has some code that I would like to execute as an API. I am using the rails-api gem.
The file is located in app/controllers/api/stats.rb.
I would like to be able to execute that script and return json output by visiting a link such as this - http://sampleapi.com/stats/?location=USA?state=Florida.
How should I configure my project so that when I visit that link it runs my code?
the file should be called stats_controller.rb app/controllers/api/stats_controller.rb
you can create an index method where you can add your code
class API::StatsController < ApplicationController
def index
#your code here
render json: your_result
end
end
in the file config/routes.rb you should add
get 'stats' => 'api/stats#index', as: 'stats'
To access the params in the url you can do it in your index method with params[:location] ,params[:state]
Here's how I would think of this:
in app/controllers/api/stats_controller.rb
module Api
class StatsController
def index
# your code implementation
# you can also fetch/filter your query strings here params[:location] or params[:state]
render json: result # dependent on if you have a view
end
end
end
in config/routes.rb
# the path option changes the path from `/api` to `/` so in this case instead of /api/stats you get /stats
namespace :api, path: '/', defaults: { format: :json } do
resources :stats, only: [:index] # or other actions that should be allowed here
end
Let me know if this works
I am a .NET developer and need to work on a API built in Ruby. Following is the API Code. Can anybody help me in getting the endpoint to it.
class Api::SessionsController < ApplicationController
respond_to :json
skip_before_filter :verify_authenticity_token
before_filter :protect_with_api_key
def update
status = true
participant_ids = []
unless params[:participants].blank?
params[:participants].each do |participant_data|
participant = Participant.where(participant_id: participant_data['participant_id']).first
unless participant.present?
status = false
participant_ids << participant_data['participant_id']
else
activity_records = participant_data['cumulative_time']['activity_records']
participant_data['cumulative_time']['activity_records'] = [] if activity_records.nil?
participant.participant_sessions.new(participant_data['cumulative_time'])
participant.save!
end
end
end
if status
render :json => {status: "OK"}
else
render :json => {error: "No participant with id # {participant_ids.join(',')}"}, :status => 422
end
end
end
I have tried to work with following way /api/sessions/
Pass the required key
passing the
participant parameter with PUT Request like below
{"participants":[{"first_name":"Demo", "last_name":"User", "email":"demouser#demouser.com", "password":"RubyNewBie","postal_code":"160055", "coordinator_name":"RubyNewBie", "coordinator_email":"info#RubyNewBie", "coordinator_phone":""}]}
Please guide me.
Thanks and Regards
By default, update action routes to /api/sessions/:id, so you should make query to that url. Also make sure that you have your route for session set up in routes.rb
Edit:
namespace :api do
resources :participants do
resources :sessions
end
end
If it looks like that, then you're using nested routing. Check:
http://guides.rubyonrails.org/routing.html#nested-resources
You'll have to use the url /api/participants/:participant_id/sessions/:session_id under that setting.
I have a controller:
class Api::V1::Account::SharingController < ApplicationController
def show
sharings = Account::Sharing.all
render json: sharings, status: :ok
end
end
The model:
path: models/account/sharing.rb
class Account::Sharing < ActiveRecord::Base
end
Route:
scope '/account' do
resource :sharing, controller: 'account.sharing', path: 'sharings'
end
I get the this error: uninitialized constant Api::V1::Account::SharingController::Account, this is because of sharings = Account::Sharing.all
In rails console, I am able to use and get data with: Account::Sharing.all
Why is this happening?
UPDATE
Changes the folder to accounts and now my SharingController sits in accounts/sharing_controller.rb and is working.
The problem is that in the controller it searches for Account::Sharing in the controller's namespace. Try prefixing it with :: to tell it to search from the 'root' namespace like so:
::Account::Sharing.all
yuo need to define routes like that.
scope '/api' do
scope '/v1' do
scope '/accounts' do
resource :sharing, controller: 'account.sharing', path: 'sharings'
end
end
end
I created a practice rails app where I have created a namespace and versioned like is demonstrated in this railscast. Everything is working fine and I can see the json output in the browser
Then I added the Rabl gem and was trying to render the rabl views but I get an empty JSON array rendered in the browser
Here is what I did systematically to get the versioning working
1) changed the routes file to look like this
App0828::Application.routes.draw do
namespace :api, defaults: { format: 'json'} do
namespace :v1 do
resources :vendors
end
end
#resources :vendors
#root to: 'vendors#index'
end
2) The created thise files
app/copntrollers/api/v1/vendors_controller.rb
Inside the vendors_controller.rb I added the following code
module Api
module V1
class VendorsController < ApplicationController
class Vendor < ::Vendor
#subclass vendor class so thatyou can extend its behaviour just for this version
#add any functions specific to this version here
end
respond_to :json
def index
respond_with Vendor.all
end
def show
respond_with Vendor.find(params[:id])
end
..........
3) Then I pointed my browser to this url "http://localhost:3000/api/v1/vendors"
And I can see the json output in my browser
4) Then I added the rabl gem
5) restarted the server
6) Changed the above file at app/copntrollers/api/v1/vendors_controller.rb
from the version above to the version below
module Api
module V1
class VendorsController < ApplicationController
class Vendor < ::Vendor
#subclass vendor class so thatyou can extend its behaviour just for this version
#add any functions specific to this version here
end
respond_to :json
def index
render 'api/v1/index.json.rabl'
end
def show
render 'api/v1/show.json.rabl'
end
.......
7) I created the following files with this code:
file: app/views/api/v1/show.json.rabl
code: object #vendor
attributes :id, :name
file: app/views/api/v1/index.json.rabl
code: object #vendors
attributes :id, :name
8) Routes file looks like this
api_v1_vendors GET /api/v1/vendors(.:format) api/v1/vendors#index {:format=>"json"}
POST /api/v1/vendors(.:format) api/v1/vendors#create {:format=>"json"}
new_api_v1_vendor GET /api/v1/vendors/new(.:format) api/v1/vendors#new {:format=>"json"}
edit_api_v1_vendor GET /api/v1/vendors/:id/edit(.:format) api/v1/vendors#edit {:format=>"json"}
api_v1_vendor GET /api/v1/vendors/:id(.:format) api/v1/vendors#show {:format=>"json"}
PUT /api/v1/vendors/:id(.:format) api/v1/vendors#update {:format=>"json"}
DELETE /api/v1/vendors/:id(.:format) api/v1/vendors#destroy {:format=>"json"}
9) Finally I went to url: "http://localhost:3000/api/v1/vendors.json"
And all I see in the browser is an empty JSON hash: "{}"
So clearly it cannot access the instance variables. Seems to be some issue with being out of scope. Im not sure how to proceed next. I couldn't find any examples online of versioning with rabl. Any suggestions? Id really appreciate it
Thanks
Where are you setting the instance variables?
First, you probably should have this line: respond_to :json in your Api::ApplicationController (or something like that, basically the controller from which every other controller in the Api module inherit).
You dont need these: render 'api/v1/index.json.rabl'.
Just set your instance variables:
def index
#vendors = Vendor.all
respond_with #vendors
end
def show
#vendor = Vendor.find(params[:id])
respond_with #vendor
end
I'm developing an application that is primarily an API gateway. In the expectation that we'll be developing multiple versions of the API over time and with the interest of having backward compatibility, I am looking to have something along the lines of:
http://host.domain.com/apiv1/:token/:module(/:id(:method))
Given this, what I am looking to do is to have a sub-routing system of my own within each API. What I'd like to have in terms of a file structure in the Controller directory is something akin to the following:
/app/controllers/apiv1_controller.rb
/app/controllers/apiv1/module_controller.rb
/app/controllers/apiv1/response_controller.rb
and eventually also have:
/app/controllers/apiv2_controller.rb
/app/controllers/apiv2/module_controller.rb
/app/controllers/apiv2/response_controller.rb
What this breaks down to is that I am unsure how to call methods within the controllers in the subdirectories, using something like:
return Apiv1::ResponseController.index
gives me:
undefined method `index' for Apiv1::ResponseController:Class
Any leads? Does this setup require that I explicitly "require" the requisite file manually?
Pasted Here in response to the question:
routes.rb
AppName::Application.routes.draw do
resources :users
match 'api-v1/:token/:module(/:id(/:method))' => 'apiv1#route'
root :to => "welcome#index"
end
apiv1_controller.rb
class Apiv1Controller < ApplicationController
protect_from_forgery
respond_to :json
def route
Rails.logger.level = 0
logger.info("ROUTE ACTION")
logger.info("params: #{params}")
Apiv1::ResponseController.index(params)
end
end
apiv1/response_controller.rb
class Apiv1::ResponseController < ApplicationController
protect_from_forgery
respond_to :json
def index(params)
Rails.logger.level = 0
logger.info("INDEX ACTION")
result = {
'success' => true,
'controller' => 'response',
'api' => 'v1'
}
render :json => result
end
end
If you are looking for versioning your REST APIs, you can use the restful_route_version gem. It also takes care of inheriting one version from another so that you don't rewrite the same REST APIs for every version.