When I post something in my Rails app (locally), it works perfectly. However, when I deploy it on Herokuapp, it breaks. Here is what I have:
#Gemfile
# Use sqlite3 as the database for Active Record
gem 'sqlite3', group: :development
gem 'pg', '0.18.1', group: :production
gem 'rails_12factor', group: :production
#database.yml
production:
<<: *default
adapter: postgresql
database: db/production.sqlite3
I then proceeded to deploy my app to Heroku like this:
git add .
git commit -m "comment"
git push heroku master
heroku run rake db:migrate
heroku run rake db:seed
I've checked my version using the following:
heroku run rake db:version
>> Current version: 20171103035018
rake db:version
>> Current version: 20171103035018
Finally, here is my controller where I perform a create action:
#suggestions_controller.rb
def create
#suggestion = Suggestion.new(suggestion_params)
if #suggestion.save
flash[:notice] = "Suggestion successfully posted!"
redirect_to root_path
else
flash[:error] = "Suggestion failed to post!"
redirect_to root_path
end
end
private
def suggestion_params
params.require(:suggestion).permit(:suggester, :ip, :suggestion_type, :title, :body)
end
I tried this on my localhost and it creates just fine, but when I deploy it on Heroku, it displays this error:
I'm pretty certain I did everything correctly and I have no idea what's breaking here.
Thanks for any help.
Edit: I just got a lead to the problem. It says that my created_at is null.
ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "created_at" violates not-null constraint
I'm researching on the web now to see how I can fix this problem.
Well, you should take a look at your logs. Heroku documented their logging here: https://devcenter.heroku.com/articles/logging
From your description, it may be something about your database setup, e.g. wrong database.yml.
If the logs don't help you, please fix the indentation of your database.yml posted above.
I figured out the problem. It was indeed this particular error message:
ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "created_at" violates not-null constraint
I had to add this line of code to my suggestions_controller.rb
def create
Suggestion.record_timestamps = true; #added this line of code
... #other logic
end
When I upvote and downvote a post, I don't want it to update the timestamps such as this:
def upvote
Suggestion.record_timestamps = false;
... #other logic
end
I redeployed my app and it works fine now.
Related
This is my routes.rb
namespace :api do
get 'suggestions/jobs', to: "suggestions#jobs"
end
My controller
class Api::SuggestionsController < ApplicationController
def jobs
#jobs = Job.job_title_search(params[:q]) #.select(:title, :label).distinct
if #jobs.present?
render json: #jobs, status: :ok
else
render json: "Not Found", status: :ok
end
end
end
and model
def self.job_title_search(q)
where('title LIKE ?', "%#{q}%").select(:title, :label).distinct
end
in the development environment like localhost:3000/api/suggestions/jobs?q=dev the data sample is
[
{"id":null,"title":"React Native Developer","label":"Top label job"},
{"id":null,"title":"Android Developer","label":"Top label job"},
{"id":null,"title":"Business Development Representative","label":"Mid label job"},
{"id":null,"title":"Node.js Developer","label":"Top label job"}
]
that means it's working, but while I pushed into the Heroku then like example.herokuapp.com/api/suggestions/jobs?q=dev it's showing
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
I know there is "Not Found" like the code is
render json: "Not Found", status: :ok
My question is why same code is not working on Heroku? and What can I do for this?
the database.yml
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
#
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: db/test.sqlite3
production:
<<: *default
database: my_project_production
username: my_project
password: <%= ENV['MY_PROJECT_DATABASE_PASSWORD'] %>
Any help appriciated.
Thanks
The if branch of your code is fine, and since dev contains records, it’s being rendered without any glitch.
In prod, OTOH, there are no records and the else branch, which is not quite correct, is tried to be rendered. And it fails, giving you the error.
Do supply a hash there instead:
else
render json: {error: "Not Found"}, status: :ok
end
Look the LIKE keyword in SQL, if you use SQLite database for development and PostgreSQL database for production then maybe it's happened, the like is working on the development environment and production environment will be ilike the like does not work, OTOH, ilike does not work in SQLite.
If so then the solution is:
Solution 1 You can change the development database to PostgreSQL, if you have worry about changing the database then follow the below
Solution 2 You can use lower(attr) like
def self.job_title_search(q)
where('lower(title) LIKE lower(?)', "%#{q}%").select(:title, :label).distinct
end
You can see the SO Answer for this.
Hope will help.
I have several sidekiq workers in my rails 4 app and can't figure out why the processes are failing. I am passing the User_id to the worker as a string but it can't seem to find the user. But when I search the same id in my console it finds the user. What am i doing wrong? Here is my code.
Controller.rb
def update
#user = current_user
if #user.bill.update_attributes(bill_params)
RandomWorker.perform_async(#user.id.to_s)
redirect_to users_dashboard_path, :notice => "Payment Informaton Updated"
else
...
end
end
Randomworker.rb
def perform(user_id)
user_id = user_id["$oid"] unless user_id.is_a?(String)
user = User.find(user_id)
user.process.update_report
user.process.save
end
My error comes back as
RandomWorker "575a..." Mongoid::Errors::DocumentNotFound: message: Document(s) not found for class User with id(s) 575a.... summary: When calling User.find with an id or array of ids, each parameter...
--EDIT--
My db config file is as shown:
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 25
timeout: 5000
And my mongoid.yml
development:
# Configure available database clients. (required)
clients:
# Defines the default client. (required)
default:
# Defines the name of the default database that Mongoid can connect to.
# (required).
database: development_db
# Provides the hosts the default client can connect to. Must be an array
# of host:port pairs. (required)
hosts:
- localhost:27017
options:
I found a solution. I had to put a monkeypatch in the sidekiq initalizer to treat the user.id as json. Apparently, mongoid struggles with this with sidekiq and although I struggled to find some documentation on it I stumbed across the answer in another unrelated question. Have to_json return a mongoid as a string
I added this in the initalizer and it seems to have fixed the issue
class BSON::ObjectId
def as_json
self.to_s
end
end
I'd advise that you include the Sidekiq::Web to view the enqueued jobs on a web interface so you can see the parameters and possibly the failures triggered.
However, this is an error I also faced a while ago too, which quite frustrated me for a while because of the number of emails I received from my error notifier(Bugsnag).
I've not found the best solution yet, but I imagine that the database was being locked for reading or some records weren't committed before attempting to use them.
Sidekiq's documentation says in your model use, after_commit :perform_sidekiq_job, on: :create.
However, I've not really tried that because I found another approach, the flip side to my new approach is that my jobs are executed much later, at times about 10minutes later.
RandomWorker.perform_in(5.seconds, user_id)
This is less likely to fail with the Sidekiq::retry option.
Read more here
I am using Elasticsearch / SearchKick / Bonsai to set up search in production on Heroku. This is working beautifully locally, but I am having trouble indexing my objects on Heroku.
in config/initializers/bonsai.rb
require 'elasticsearch/model'
if ENV['BONSAI_URL']
Elasticsearch::Model.client = Elasticsearch::Client.new({url: ENV['BONSAI_URL'], logs: true})
end
in lib/tasks/elasticsearch.rb
require 'elasticsearch/rails/tasks/import'
in user.rb
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
searchkick
def search_data
attributes.merge(
profile_name: profile.name(&:name),
book_title: books.map(&:title)
)
end
gemfile
gem 'bonsai-elasticsearch-rails' #in the production group
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
gem "searchkick"
I ran: heroku config:add BONSAI_URL=mybonsaiurl
But, when I try to reindex with: heroku run rake searchkick:reindex CLASS=User
I get: URI::InvalidURIError: the scheme http does not accept registry part: :9200 (or bad hostname?)
Or when I do: User.elasticsearch.create_index! force: true
I get: User.elasticsearch.create_index!: command not found
It seems like SearchKick or something is set to 9200 by default but I am not sure how to change it or whether it should look for my app URL or the Bonsai URL -- I am really lost and seem to have missed a step somewhere?
Thanks for any help!
Solved thanks to Heroku support team.
I was trying to use two different clients - the official Elasticsearch rails client, and Searchkick. I went thru and removed all the configuration for the 3 Elasticsearch/Bonsai gems, and edited this file:
config/initializers/bonsai.rb
if ENV['BONSAI_URL']
# Elasticsearch::Model.client = Elasticsearch::Client.new({url: ENV['BONSAI_URL'], logs: true})
Searchkick.client = Elasticsearch::Client.new({url: ENV[‘BONSAI_URL’], logs: true})
end
Now, I can run: heroku run rake searchkick:reindex:all
to index my models.
More here: http://danifankhauser.com/post/104137889438/rails-how-to-index-searchkick-on-heroku-with
I am using RoR (3.2.2) and SQLite 3 (1.3.5). When I initially generate a model I am able to successfully create a database. However, whenever I try to use the migration generator it appears to not have any issues in the command line (no errors), but when I check the database nothing has updated or changed.
For example, I create this database:
$ rails generate model User name:string email:string
db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
And I run a migration:
$ bundle exec rake db:migrate
So far so good, I check my database using SQLite Database Browser and everything looks as it should.
Then if I want to add an index:
$ rails generate migration add_index_to_users_email
db/migrate/[timestamp]_add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
I run a migration:
$ bundle exec rake db:migrate
And command line gives me the following:
bundle exec rake db:migrate
== AddIndexToUsersEmail: migrating ===========================================
== AddIndexToUsersEmail: migrated (0.0000s) ==================================
However, when I check my database using SQLite Database Browser it isn't updated. I get the same results if I try to add new columns to the table, etc. The only way I have been able to do migrations is manually updating the database using the SQLite Database Browser. Any help as to why it is not working through Rails and the command line would be greatly appreciated.
Here is my gemfile:
source 'https://rubygems.org'
gem 'rails', '3.2.2'
gem 'bootstrap-sass', '2.0.0'
group :development, :test do
gem 'sqlite3', '1.3.5'
gem 'rspec-rails', '2.8.1'
gem 'annotate', '~> 2.4.1.beta'
end
group :assets do
gem 'sass-rails', '3.2.4'
gem 'coffee-rails', '3.2.2'
gem 'uglifier', '1.2.3'
end
gem 'jquery-rails', '2.0.0'
group :test do
gem 'capybara', '1.1.2'
end
group :production do
gem 'pg', '0.12.2'
end
Database.yml
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Example of successfully adding a column:
rails generate migration add_password_digest_to_users password_digest:string
invoke active_record
create db/migrate/20120318235656_add_password_digest_to_users.rb
$ subl db/migrate/[timestamp]_add_password_digest_to_users.rb
$ bundle exec rake db:migrate
== AddPasswordDigestToUsers: migrating =======================================
-- add_column(:users, :password_digest, :string) -> 0.0008s
== AddPasswordDigestToUsers: migrated (0.0009s) ==============================
Example of unsuccessfully adding a column:
$ rails generate migration add_remember_token_to_users
invoke active_record
create db/migrate/20120319010623_add_remember_token_to_users.rb
$ subl db/migrate/[timestamp]_add_remember_token_to_users.rb
$ bundle exec rake db:migrate
== AddRememberTokenToUsers: migrating ========================================
== AddRememberTokenToUsers: migrated (0.0000s) ===============================
Notice when it fails to update the database the migration time is zero. I'm not sure what I am doing wrong. Thanks in advance for any suggestions.
I solved the problem undoing the last migration with
rails destroy migration add_index_to_users_email
Then I closed my terminals to ensure that all db connections were closed, then I run
rake db:reset
Finally, running the same commands again
rails generate migration add_index_to_users_email
Updating the file with the same content and running
rake db:migrate
All the same commands and files that were not working before now worked at all (for me).
I hope this works for you as well.
I think what happens is you get the syntax slightly wrong (it's insanely tricky) then you get an empty migration which doesn't do anything.
I would double check that the actual migration file has add column. I often end up manually putting the actual change (or up/down) in.
As t Harrison says, adding an index is more subtle - as you sure it doesn't get added if you refresh the sqlite borwser. The examples you gave that worked... are to add columns...
The output you posted from the add index example shows that the migration is indeed running ... but you report it's not actually doing anything. Try bundle exec rake:db rollback (with optional STEP=n to go more than one step back). This really should "just work", and a case of an index might be a little subtle -- try adding a column or something (which you said you have done, but, just to be sure). Does it really not work? How can you tell?
I am trying to push a simple app up to heroku and run:
heroku rake db:migrate
But I get the following error:
rake aborted!
PGError: ERROR: relation "posts" does not exist
: SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"posts"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
My migration looks like this:
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :source
t.string :tweetid
t.string :pure
t.string :media
t.string :destination
t.datetime :time
t.timestamps
end
end
end
And, after referring to another SO answer, I have included the following in my Gemfile:
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.1.4'
gem 'coffee-rails', '~> 3.1.1'
gem 'uglifier', '>= 1.0.3'
gem 'pg'
end
Thank you in advance for any help!
--- UPDATE ---
The main reason I am confused is that this all works locally, just not when I run the migration on heroku.
Here is the error I get now:
rake aborted!
Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (pg is not part of the bundle. Add it to Gemfile.)
I have been looking at this question:
Heroku error when launch rails3.1 app missing postgres gem
I am almost-certain my database.yml should not look like this (seeing as I need to be running postgresql!!!):
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Serious apologies for the nubishness here. Thank you for your help in advance!
Also tried this link: Uploading to Heroku DB rake:migrate problem
create_table :posts
Didn't you forget the s? The table names should be plural.
I just ran: bundle exec rake db:migrate and it worked
I had a similar problem, but it wasn't caused by the migration or the Gemfile. I had 4 models setup in a polymorphic relationship. Removing the statement
belongs_to :assetable, :polymorphic => true, :dependent => :destroy
and removing the subclass' acts_as_* declarations was enough to enable the db:migrate to successfully complete. I then added back the statements in the models and everything worked great. I'm not exactly sure why this is the case, but if you are in a similar situation this may help temporarily until a better solution presents itself.
My situation is polymorphic multi-table inheritance scheme between one parent and 3 objects using http://mediumexposure.com/multiple-table-inheritance-active-record/ as a baseline.
If you're using ActiveAdmin, whichever table PG says doesn't exist, comment out the contents of that ActiveAdmin rb file.
For example, for this case PGError: ERROR: relation "posts" does not exist, comment out the entire contents of app/admin/posts.rb, then uncomment after you've done your migrations.
Robin probably has it right but just in case...
Check the filename/timestamps on your migrations. These get run in sequence. I had an issue where a generator that made my migrations was putting the foreign table first...I switched the file names and it worked.
It's a long shot but I thought I'd put that out there.
In my case, I was doing rename_table in my migration, after having already modified my model name to reflect the new table name. I had moved User into User::User. The users table needed to be renamed to user_users, so my migration looked like
class RenameUsersTableWithPrefix < ActiveRecord::Migration
def up
rename_table :users, :user_users
end
def down
rename_table :user_users, :users
end
end
Instead of
app/models/user.rb
I now had
app/models/user.rb
app/models/user/user.rb
with the latter containing the User::User model, and the former containing simply
module User
def self.table_name_prefix
"user_"
end
end
It was this class method in the newly added User module that was giving me the PGError when running rake db:migrate like the OP had. Temporarily removing this class method while I ran my migration allowed the migration to run smoothly.
I was having the same problem. I ran heroku run rake db:migrate and that solved the problem.