In rails project, I made api folder and I added this code to my application.rb file:
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
In my api folder I have created game_server.rb file:
module GameServer
module Entities
class Test < Grape::Entity
expose :id
end
end
class API < Grape::API
version 'v1', using: :path
prefix :api
format :json
get :details do
present Basis.all, with: GameServer::Entities::Test
end
end
end
All code inside GameServer module. When I hit http://localhost:3000/api/v1/details in my browser I het this error:
uninitialized constant Grape::Entity.
I even tried to put my Entities module in other file, still does not work.
WHY?
You are using old version of grape, change your grape version:
gem 'grape', '~> 0.11.0'
You can refer to this repository: https://github.com/philcallister/rails-grape-entity
Just add
gem 'grape'
gem 'grape-entity'
into your Gemfile
Related
I am following this tutorial
https://www.youtube.com/watch?v=fgn12-Yc-Sg
I have in my application.rb
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
Then on my app folder I have an api folder and inside of that the module folder converter
/app/api/converter/currency.rb
module Converter
class Currency
resource :converter do
get :exchange do
params
end
end
end
end
Now rails finds the Converter module on the console but it gives error for the Currency class
I want to create a Messenger Bot used by different users for their Facebook pages. I created a rails app and use the facebook-messenger gem.
I successfully created the bot and it works when I do the set up for one page. Now, I follow the instructions to make my bot live on multiple Facebook Pages (see "Make a configuration provider" section).
I'm new to rails and I'm not sure where to put the class ExampleProvider? I put it in my config/application.rb file:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module BotletterApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.paths.add File.join('app', 'bot'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'bot', '*')]
end
class BotProvider < Facebook::Messenger::Configuration::Providers::Base
def valid_verify_token?(verify_token)
bot.exists?(verify_token: verify_token)
end
def app_secret_for()
ENV['APP_SECRET']
end
def access_token_for(page_id)
bot.find_by(user_id: page_id).page_access_token
end
private
def bot
MyApp::Bot
end
end
Facebook::Messenger.configure do |config|
config.provider = BotProvider.new
end
end
Then I have my app/bot/setup.rb file to create the bot. I don't know how to use the provider I created in place of the ENV variables?
require "facebook/messenger"
include Facebook::Messenger
Facebook::Messenger::Subscriptions.subscribe(access_token: ENV["ACCESS_TOKEN"])
Facebook::Messenger::Profile.set({
get_started: {
payload: 'GET_STARTED_PAYLOAD'
}
}, access_token: ENV['ACCESS_TOKEN'])
I searched in the Rails documentation how to make it work but unfortunately could not find anything.
UPDATE:
Now I'm able to set up the bots for different pages. Unfortunately, the following line of my ConfigProvider is getting an error:
config/initializers/config_provider.rb
def bot
Rails.application.class.parent::Bot
end
I'm getting the following error:
NameError (uninitialized constant BotletterApp::Bot):
config/initializers/config_provider.rb:17:in bot'
config/initializers/config_provider.rb:7:inapp_secret_for'
Do you know how should I name my app?
My BotModule:
module BotletterApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.paths.add File.join('app', 'listen'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'listen', '*')]
end
end
UPDATE, it works with ::Application, here is the new file:
class ConfigProvider < Facebook::Messenger::Configuration::Providers::Base
def valid_verify_token?(verify_token)
ENV['VERIFY_TOKEN']
end
def app_secret_for(page_id)
ENV['APP_SECRET']
end
def access_token_for(page_id)
CoreBot.find_by_page_id(page_id).page_access_token
end
private
def bot
BotletterApp::Application
end
end
Facebook::Messenger.configure do |config|
config.provider = ConfigProvider.new
end
The problem is I get the following error unless my db query seems working (it works in the rails console):
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column:
page_id.id: SELECT "core_bots".* FROM "core_bots" WHERE
"page_id"."id" = ? LIMIT ?):
Moving to an answer for improved readability ;)
Regarding 'plain'... Instead of
def bot
BotletterApp::Application
end
use
def bot
Bot
end
or (it looks like you named your model containing all pages CoreBot(?) (assuming you have a typical ActiveRecord model in /app/models/core_bot.rb, I was assuming Bot)
def bot
CoreBot
end
Then you should be able to use the template code from the README.md
As for your latest problem: it seems like the access_token_for-method gets called with a hash, searching with something like {id: 1}. You might want to check where that value is coming from. I would suggest to take a few steps back, and stay closer to the template code.
Below is the configuration I used to build API's using Grape.
But I am not able to build documentation using Swagger
Gems:
gem 'grape'
grape-0.13.0
gem 'grape-swagger-rails'
grape-swagger-rails-0.1.0
gem 'rack-cors', :require => 'rack/cors'
rack-cors-0.4.0
config/application.rb
require 'rack/cors'
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '**', '*.rb')]
config/initializers/swagger.rb
GrapeSwaggerRails.options.url = '/swagger_doc.json'
GrapeSwaggerRails.options.app_url = "http://api.lvh.me:3000"
config/routes.rb
constraints(subdomain: 'api') do
mount API::Base => '/'
end
mount GrapeSwaggerRails::Engine, at: "/apidocs"
app/api/api/base.rb
require 'grape-swagger'
module API
class Base < Grape::API
default_format :json
mount API::V1::Base
add_swagger_documentation(
api_version: "v1",
hide_documentation_path: true,
mount_path: "/",
hide_format: true
)
end
end
Issue:
When I hit http://lvh.me:3000/apidocs. I'm getting below error below green Nav bar.
Can't read swagger JSON from http://api.lvh.me:3000/swagger_doc.json
When I hit http://api.lvh.me:3000/swagger_doc.json. Getting below response.
{"error":"Not Found"}
I am not able to figure out what am doing wrong. Need help in rendering Swagger documentation with grape framework.
In config/initializers/swagger.rb you set the URL to your schema to /swagger_doc.json and to mount_path in the method add_swagger_documentation you pass '/'. Shoudn't it be /swagger_doc ?
I want to do an API for an Android app. When searching, I found {grape}. I'm following this tutorial, but I have a problem launching the Rails server:
=> Booting WEBrick
=> Rails 4.0.2 application starting in development on http://0.0.0.0:80
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activesupport-4.0.2/lib/act
ive_support/dependencies.rb:464:in `load_missing_constant': Unable to autoload c
onstant Usuarios, expected C:/Sites/appCerca/app/api/v1/usuarios.rb to define it
(LoadError)
My directory:
app
..api
....api.rb
....v1
......root.rb
......usuarios.rb
and the files:
#application.rb
module AppCerca
class Application < Rails::Application
config.paths.add "app/api", glob: "**/*.rb"
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
end
end
#routes.rb
AppCerca::Application.routes.draw do
mount API::Root => '/'
[...]
#app/api/root.rb
module API
class Root < Grape::API
prefix 'api'
mount API::V1::Root
end
end
# app/api/v1/root.rb
module API
module V1
class Root < Grape::API
mount API::V1::Usuarios
end
end
end
# app/api/v1/usuarios.rb
module API
module V1
class Usuarios < Grape::API
version 'v1'
format :json
resource :usuarios do
desc "Return list of authors"
get do
Usuario.all
end
end
end
end
end
Why am I getting this error? I am using Ruby 1.9.3p484 and Rails-4.0.2.
Try either
Moving your API code's files from app/api to app/api/api, or
Moving your API classes outside the API module (i.e. deleting all the module API lines and their corresponding end statements).
From Grape's documentation:
Place API files into app/api. Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class. In our example, the file name location and directory for Twitter::API should be app/api/twitter/api.rb.
Thus the correct location for your API::Root class would actually be app/api/api/root.rb.
With this change your code starts and works fine for me on Rails 4.0.2.
I've placed the file rack_app.rb with simple Rack application in the lib directory:
class RackApp
def call env
[200, {}, 'Hello']
end
end
Then I've added this route:
match 'rack' => RackApp
And when I try to launch the rails server I get the following error:
config/routes.rb:65: uninitialized constant RackApp (NameError)
Rails 3 has no more autoloading by default. So you need require your file
require 'lib/rack_app.rb'
Or come back the autoloading in application.rb
config.autoload_paths += %W( #{config.root}/lib )
Include require 'email_format_validator' in the model.