Heroku deployment for Ruby / Sinatra / Postgres app "PG::ConnectionBad" - ruby

I’ve deployed my Ruby app on Heroku, however when looking to register or login I’m having an internal server error. My app is built on Sinatra and Rake.
When doing heroku logs -tail I’m having the following error message:
PG::ConnectionBad - connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
I installed the heroku Postgres add-on. I migrated my db with the following command:
heroku pg:push makersbnb DATABASE --app makersbnb-challenge
Here is one of my lib file with my PG connections:
require 'bcrypt'
class User
attr_reader :user_id, :username
def initialize(user_id:, username:)
#user_id = user_id
#username = username
end
def self.register(username:, password: )
if ENV['ENVIRONMENT'] == 'test'
connection = PG.connect(dbname: "makersbnb_test")
else
connection = PG.connect(dbname: 'makersbnb')
end
encrypted_password = BCrypt::Password.create(password)
result = connection.exec_params("INSERT INTO users (username, password)
VALUES ($1, $2)
RETURNING user_id, username, password;",[username, encrypted_password])
User.new(user_id: result[0]['user_id'], username: result[0]['username'])
end
def self.authenticate(username:, password:)
if ENV['ENVIRONMENT'] == 'test'
connection = PG.connect(dbname: "makersbnb_test")
else
connection = PG.connect(dbname: 'makersbnb')
end
result = connection.query(
"SELECT * FROM users WHERE username = $1",
[username]
)
return unless result.any?
return unless BCrypt::Password.new(result[0]['password']) == password
User.new(user_id: result[0]['user_id'], username: result[0]['username'])
end
end
Here is my Gemfile:
source "https://rubygems.org"
ruby '3.1.0'
gem "sinatra"
gem "sinatra-contrib"
gem "rake"
gem 'pg'
gem 'webrick'
gem 'bcrypt'
gem 'rack-flash3'
gem "sinatra-activerecord" # for Active Record models
gem 'capybara', group: :test
gem 'rspec', group: :test
I also created a database.yml file based on other instructions I read but I'm not sure if it applies in this case:
# database.yml file
default: &default
adapter: postgresql
encoding: unicode
pool: 5
test:
<<: *default
database: makersbnb_test
production:
<<: *default
database: makersbnb
Here is the repo
Here is the app
Help!

I will try to explain the problem, but also point some other flaws of Your current approach
To connect to remote database You should specify some options in
connection = PG.connect(dbname: "makersbnb")
You should specify not only dbname option but also:
host
user
password
Those can be retrieved from heroku postgresql config
connection = PG.connect(dbname: "makersbnb", host: <db_host>, user: <db_user>, password: <db_password>)
REMEMBER DON'T SET THOSE VALUES IN YOUR CODE
Instead You can use env variables.
Your config file is not doing anything in this approach
In the script You also don't use ActiveRecord. To do so Your model class should inherit from ActiveRecord::Base, something like this:
class User < ActiveRecord::Base
end
Here You can find some information how to use ActiveRecord without Rails framework: https://www.devdungeon.com/content/ruby-activerecord-without-rails-tutorial
And also some more information how to use it in sinatra specifically:
https://github.com/sinatra-activerecord/sinatra-activerecord

Related

Codeship, Sinatra, ActiveRecord - configuration

I have a sinatra app working on my computer and am trying to get the tests to run on Codeship. I've reduced it to a tiny subset to see if I can sort out the problem I am having. I would greatly appreciate another pair of eyes...
Here are the key files:
Rakefile:
require 'sinatra/activerecord/rake'
require 'rake/testtask'
require_relative "demo_app"
Rake::TestTask.new do |t|
t.pattern = "test/*_test.rb"
end
database.yml
development:
adapter: sqlite3
database: db/development.sqlite3
test:
adapter: sqlite3
database: db/test.sqlite3
production:
url: <%= ENV['DATABASE_URL'] %>
demo_app.rb:
require 'sinatra/activerecord'
require './models/event'
require './models/person'
require './models/registration'
require 'pry-byebug'
migrations:
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :name
t.date :date
end
end
end
test_helper.rb:
ENV['RACK_ENV'] = "test"
ENV["SINATRA_ENV"] = "test"
require_relative '../demo_app'
require 'minitest/autorun'
require 'rack/test'
ActiveRecord::Migration.maintain_test_schema!
event_test.rb:
require_relative './test_helper.rb'
describe Event do
it "can add events" do
Event.create(name: "An Event")
Event.create(name: "Another Event")
Event.all.size.must_equal 2
end
end
So, with that context I setup Codeship. Here are the key settings there:
Setup commands:
rvm use 2.2.2
bundle install
RACK_ENV=test bundle exec rake db:migrate
Test Pipeline (1 of 1)
rake test
And now when I push to git, and codeship picks it up I get this error on line 1 of demo_app.rb which is a require to sinatra/activerecord:
rake aborted!
Database URL cannot be empty
.....
It seems that for some reason, it is not paying attention to the fact that I am running in test mode and so it should use the test clause of database.yml.
Thoughts?

Sinatra with Postgres and ActiveRecord | Error Pushing to Heroku is: Invalid DATABASE_URL

I have an application written in Sinatra that works locally but that I cannot seem to push up to heroku.
When I attempt to push to heroku I get the following error:
-----> Writing config/database.yml to read from DATABASE_URL
Could not detect rake tasks
ensure you can run $ bundle exec rake -P against your app with no environment variables present
and using the production group of your Gemfile.
This may be intentional, if you expected rake tasks to be run
cancel the build (CTRL+C) and fix the error then commit the fix:
rake aborted!
Invalid DATABASE_URL
My Gemfile
source 'https://rubygems.org'
ruby '2.0.0'
gem 'sinatra', require: 'sinatra/base'
gem "pg"
gem "activerecord"
gem "sinatra-activerecord"
gem "rake"
gem 'minitest', require: false
gem 'rack-test', require: false
gem 'faraday'
gem 'json'
gem 'minitest-reporters'
My database.yml file
development:
adapter: postgresql
encoding: unicode
database: calendar_development
host: localhost
password:
test:
adapter: postgresql
encoding: unicode
database: calendar_test
pool: 5
host: localhost
password:
My config.ru
require './app'
run Sinatra::Application
ENV['RACK_ENV'] ||= 'development'
Procfile
web: bundle exec rackup config.ru -p $PORT
Rakefile
require "sinatra/activerecord/rake"
require 'rake/testtask'
require "./app"
task :default => :test
env = ENV["SINATRA_ENV"] || "development"
Rake::TestTask.new do |t|
t.libs << 'test'
t.test_files = FileList["test/**/*_test.rb"]
t.verbose = false
end
The app.rb
require 'sinatra'
require 'sinatra/activerecord'
require 'json'
Dir[File.dirname(__FILE__) + '/models/*.rb'].each {|file| require file }
env_index = ARGV.index("-e")
env_arg = ARGV[env_index + 1] if env_index
env = env_arg || ENV["SINATRA_ENV"] || "development"
use ActiveRecord::ConnectionAdapters::ConnectionManagement # close connection to the DDBB properly...https://github.com/puma/puma/issues/59
databases = YAML.load_file("config/database.yml")
ActiveRecord::Base.establish_connection(databases[env])
if env == 'test'
User.destroy_all
end
I removed all the environment test from my app.rb file and moved it to environments:
app.rb
require './config/environments'
Then I changed the DB setup - first of all, removed all the ENV[SINATRA_ENV]
environments.rb
configure :production, :development, :test do
db = URI.parse(ENV['DATABASE_URL'] || 'postgres://localhost/calendar_development')
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:username => db.user,
:password => db.password,
:database => db.path[1..-1],
:encoding => 'utf8'
)
end
I changed my Rakefile
namespace :db do
task :seed do
seed_file = File.join('db/seeds.rb')
load(seed_file) if File.exist?(seed_file)
end
end
I followed sybohy's advice and in my config.ru file, I removed the last line - leaving
config.ru
require './app'
run Sinatra::Application
I ran:
heroku addons | grep POSTGRES
grabbed the name of the db (HEROKU_POSTGRESQL_JADE)
heroku pg:reset HEROKU_POSTGRESQL_JADE
and then migrated
heroku run rake db:migrate
So far this seems to have fixed the errors! I will update if I find more!

Mongoid error in heroku: Database should be a Mongo::DB, not a nil class

I have a Sinatra app on heroku and it keeps crashing due to this error:
app/vendor/bundle/ruby/1.9.1/gems/mongoid-1.2.14/lib/mongoid/config.rb:52 in 'master': Database should be a Mongo::DB, not a nil class
I set up Mongoid 3.x according to the heroku instructions, and the app works on my local machine, so I'm not sure what's causing this problem. My gemfile looks like this:
source "https://rubygems.org"
ruby "1.9.3"
gem 'sinatra'
gem 'mongo'
gem 'mongoid'
gem 'bson_ext'
gem 'json'
gem 'nokogiri'
gem 'aws-s3', '0.6.2', :require => 'aws/s3'
gem 'sinatra-reloader'
gem 'debugger'
gem 'thin'
Here's my mongoid.yml:
development:
sessions:
default:
database: db
hosts:
- localhost:27017
production:
sessions:
default:
uri: <%= ENV['MONGOHQ_URL'] %>
options:
skip_version_check: true
safe: true
And here's my app file:
require 'bundler/setup'
require 'sinatra'
require 'json'
require 'mongo'
require 'mongoid'
Mongoid.load!('mongoid.yml', :production)
def get_connection
return #db_connection if #db_connection
db = URI.parse(ENV['MONGOHQ_URL'])
db_name = db.path.gsub(/^\//, '')
#db_connection = Mongo::Connection.new(db.host, db.port).db(db_name)
#db_connection.authenticate(db.user, db.password) unless (db.user.nil? || db.user.nil?)
#db_connection
end
db = get_connection
class Model1
include Mongoid::Document
field :name, :type => String
end
I shouldn't have to specify a database name since I'm using the uri field, so I'm not sure why the database if nil?

Ldap gem throws no connection to server exception in Rails

Trying to establish a connection from a module in Rails and get no connection to server. I have tested the same code outside Rails and it works fine.
require 'rubygems'
require 'net-ldap'
module Foo
module Bar
class User
attr_reader :ldap_connection
def initialize
#ldap = Net::LDAP.new(:host => "<ip-number>", :port => 389)
#treebase = "ou=People, dc=foo, dc=bar"
username = "cn=Manager"
password = "password"
#ldap.auth username, password
begin
if #ldap.bind
#ldap_connection = true
else
#ldap_connection = false
end
rescue Net::LDAP::LdapError
#ldap_connection = false
end
end
end
end
end
Getting Net::LDAP::LdapError: no connection to server exception.
I found a solution/workaround for my problem with auto-loading in Rails. Added a new initializer to ensure that all Ruby files under lib/ get required:
Added config/initializers/require_files_in_lib.rb with this code
Dir[Rails.root + 'lib/**/*.rb'].each do |file|
require file
end
Read more about the workaround: Rails 3 library not loading until require

MongoId - uninitialized constant App::Mongo (NameError)"

In Sinatra app I have
#config.rb
require 'mongoid'
class App
configure do
Mongoid.configure do |config|
name = "my_db"
host = "localhost"
config.master = Mongo::Connection.new.db(name)
config.slaves = [Mongo::Connection.new(host, 27017, :slave_ok => true).db(name)]
config.persist_in_safe_mode = false
end
end
end
#Gemfile
gem "mongoid", "~> 3.0.0"
gem "bson_ext"
and it gives me an error "`const_missing': uninitialized constant App::Mongo (NameError)"
How do I fix it?
This is due to the fact that Mongoid 3.x no longer uses the 10Gen Ruby driver so Mongo module will not be loaded by require 'mongoid'. You need to use the new Mongoid.load! method. You may have to change your config.yml file a bit as the syntax has changed. Please see http://mongoid.org/en/mongoid/docs/installation.html

Resources