Unable to access model data from action - ruby-on-rails

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

Related

Work with default routes but custom routes give uninitialized constant Api::V1::UserController

I know this questions is asked several times but I checked those answers but nothing seems to fix my issue.
users_controller.rb on path app/controllers/api/v1/
module Api
module V1
class UsersController < ApplicationController
def create_user
#users = User.new(user_params)
if #users.save
render json: { status: '201', message: 'User created successfully' }
else
render json: { status: '400', message: 'Invalid user info', data: #users.errors }
end
end
def user_params
params.permit(:first_name, :last_name, :email, :password)
end
end
end
end
routes.rb
namespace 'api' do
namespace 'v1' do
post "user/createuser", to: "user#create_user"
end
end
What I have tried:
Checked the directory structure it is as mentioned
Restarted the server and checked
Folder name: all simple controllers > api > v1
But this works fine when I changed the routes.rb
post "user/createuser", to: "user#create_user"
to resource :users
and
def create_user
to def create
Why things does not work when I define custom routes instead of using default routes? How to get this work with custom routes
Due to Rails conventions I believe you need to update your route with
post "user/createuser", to: "users#create"
instead of
post "user/createuser", to: "user#create_user"

Ruby API - Accept parameters and execute script

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

Rails: How do I create links like "mysite.com/fFD2Zad" instead of "mysite.com/?var=fFD2Zad"

I want users to have codes to invite other users to the website. I know how I could generate random strings but how can I make it so that each user has a link such as "mysite.com/fFD2Zad" that uses the code instead of having a bulky link like "mysite.com/?var=fFD2Zad"?
Rails.application.routes.draw do
get '/:invitation_code', to: 'users#welcome'
end
class UsersController < ApplicationController
def welcome
p params
end
end
Check yourserver.com/fFD2Zad
#=> {"controller"=>"users", "action"=>"welcome", "invitation_code"=>"fFD2Zad"}
You can add the lowest priority route in the end of routes.rb:
get '/:user_code', to: 'users#profile', user_code: /[a-zA-Z0-9]{7}/
And process it in your controller:
def profile
# => params[:user_code]
...
end

Circular dependency detected while autoloading constant Api::V1::VersionsController

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

Using versioning in a Rails API app- Cannot render JSON for a particular controller action

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

Resources