Database attribute saving in Development but not in Production - ruby-on-rails

I'm getting a database error in production. But in development no error.
ActiveModel::MissingAttributeError (can't write unknown attribute `invited_by_id`):
invited_by_id is a column added by the Devise Invitable gem to my User table. I encountered this error after pushing my Devise Invitable implementation to production for the first time and then attempting to invite a new user.
I have confirmed that invited_by_id IS present in both my development and production tables. I have checked this multiple times via Rails console for each environment. I have also done rake db:migrate twice for good measure (in production) with the first time adding the Devise Invitable columns and the second time, of course, having no new migrations to run since the columns were already added. There are also numerous other columns added by Devise Invitable to the same User table that were successfully migrated and are not creating errors. I have successfully edited one as well. (Google Searches, Devise Invitable Github issues, and a thorough review of my development and production environment fields have yielded nothing but encouragement to check that the column is present -- which it is.)
Is there something to be aware of with Devise Invitable, User tables, or with development versus production databases for a situation like this? For some additional context, I am using Devise Invitable 1.5.5, Rails 4.2.4, and my production database is on Heroku.
Thank you!

ActiveModel::MissingAttributeError (can't write unknown attribute `invited_by_id`)
Looking at this error message, you are missing invited_by_id column in your production database. Make sure you run your migrations on production environment and try again. That should fix your problem.
Here is the same issue reported on the gem's github page.
You can also try restarting your heroku app which seems to fix this type of issues many times :)

Related

Fixing this Error: NameError (uninitialized constant ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column)

There are two apps. One of the apps is using rails 4.1.2. The other app is using rails 5.0.1. Here is how the rails 5 app works: it checks if the user is logged in:
If the user is logged in: then the user should be able to proceed forward.
If the user is NOT logged in, then it redirects them to the rails 4 app (which is where the user can log in). Once the user is logged in with the rails 4 app: the user should be able to access the rails 5 app no problem.
I am currently using the following gems in my Rails 5 project:
gem 'mysql2', '~> 0.4.4'
gem 'activerecord-session_store', '~> 1.0'
I then have the following in my config/initializers/session_store.rb file:
Rails.application.config.session_store :active_record_store, :key => ‘SOME_KEY’
Currently: if the user is not logged in: then it successfully redirects the user. The issue is when the user is logged in. I get this error when the logged in user attempts to access the rails 5 app:
NameError (uninitialized constant ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column)
I do notice that the app is successfully connecting to the database
The app also appears to access the sessions table on initial request (when the user is not logged in).
Any suggestions on what is triggering this error and how to fix it? Ultimately: it almost appears as though rails 5 is incompatible with activerecord-session_store and mysql2.
We were eventually able to figure it out.
The Marshal module can serialize ruby objects to the database. It can also deserialize stuff from the database in order to recreate the objects.
When you serialize an object, there appears to be some low level info that goes in there too, like the mysql2 connection adapter.
When the Rails 5 app tries to deserialize the data, it throws this error because the constant that exists in the MySql2 connection adapter for Rails 4 does not exist in the Rails 5 version of that adapter.
Our work around was to just not store or retrieve any of the serialized objects from the sessions table for our rails 5 app. That did the trick.
If we had really needed to retrieve serialized objects from the sessions table for our rails 5 app: then I think we would have had to come up with a custom solution.
Hope this helps others in the future!
It may be due to changes in release i.e. Rails 5.0.
As In Ruby on Rails 5.0 Release Notes:
Removed support for the legacy mysql database adapter from core. Most users should be able to use mysql2. It will be converted to a separate gem when we find someone to maintain it.
Deprecated passing arguments to #tables - the #tables method of some adapters (mysql2, sqlite3) would return both tables and views while others (postgresql) just return tables. To make their behavior consistent, #tables will return only tables in the future.
Difference in constant as you described in your answer may be due to they going to change gem for mysql2 adapter.

Heroku throws error where local host does not

I have a rails app running on heroku. Locally everything works fine. However, upon pushing to heroku there is an error.
The logs state this:
app/controllers/orders_controller.rb:7:in `create'
ActiveRecord::UnknownAttributeError (unknown attribute: ammo_id):
Started POST "/orders?ammo_id=4" for 96.235.177.110 at 2014-08-09 00:03:09 +0000
I.e. that this is an error in my orders_controller on line 7. This is line 7:
#order = #cart.orders.build(ammo_id:params[:ammo_id])
Locally this run perfectly. However, on heroku it does not. I changed that line to:
#order = #cart.orders.build(:ammo_id => params[:ammo_id])
And now it works on heroku. So my question is, why does the first syntax not work on heroku? Does it have to do with versions?
Attributes
Having just answered another question like this, I'd say the problem is almost certainly to do with your Heroku DB not having the attributes it needs to run
The issue here is that your Rails development DB & Heroku production DB will be completely different, and as such, you need to make sure you have migrated your Heroku db as you have your local one
The way to fix it will be to run the following on your local machine:
$ heroku run rake db:migrate
--
Whenever Rails throws ActiveRecord::UnknownAttributeError - it means Rails does not have access to the particular attribute on your model class.
To understand this, you must remember that Rails is basically a series of classes which load with each request. These classes, as per the object-orientated structure, are populated by a series of attributes. These attributes, in the case of Rails, are pulled from the database -- meaning if your application cannot find specific attributes, it simply means the database doesn't have them
To fix this, you have to ensure you have the required columns present in your db. The most common instance of this issue is a lack of foreign_key in your various models
It might have to do with Database Migrations. Make sure you run heroku run rake db:migrate <your branch stuff here> after every push so that our schema updates to your new models.
Also,Your heroku may be defaulting to an older version of ruby. The => syntax for hashes was the default in older versions of ruby. But now {key: value} is a new acceptable format. Though this is very unlikely.

Devise in rails giving error on heroku

I am using devise with mongoid. App has two devise models users and investors. When I sign-up for each in localhost it works fine but on heroku when I submit form the page get redirects to app/users or app/investors and I got 500 service internal error. In the app the views directory of users and investors are separately defined.
Any guesses?
Finally solved the issue was the mongodb service, they actually reset the password, so I have to change that in mongoid.yml. My advice for people working with service:
1) Start your debugging with config files the username and password before jumping to plugin code. I spend 5 hours in debugging devise internal code and problem was somewhere else.

Role table gone, Rails Devise on Heroku

am new to rails & this is my first app .. I used devise & CanCan for authentication & authorization & there was a predefined set of roles for every user that I can assign it to ... Working perfectly on my local machine .. once deployed to Heroku & migrated the database everything seemed in place but when I tried to assign a role to a user there was none .
Any idea what's wrong?
I also wanted to disable the sign-up & only allow admins to create users
Thanks in advance
EDIT:
After too much searching I found out that the missing part is the Role table from the rolify gem, for some reason it refuses to migrate on the PostgreSQL/Heroku.
& the issue is raised in this link, still didn't find a solution that worked for me
https://github.com/EppO/rolify/issues/76
You might need to run all the migrations on Heroku. Do this: heroku run rake db:migrate and try again.

Rails 3.2 has_secure_password fails silently when deployed to Heroku

I upgraded the authentication in my application to use Rails 3.1's has_secure_password facility. In the process, I created a page to allow users to change their passwords. I tested it and it works on my development machine, both in development and production environments.
When I deployed the application to Heroku, I went to try it and it seemed to work, except when I logged out and logged back in, my password was unchanged. I tried changing the password manually in the console and that works fine. If I try to enter different text for the password and confirmation, it shows the validation it is supposed to, which means the password is getting sent to the app correctly.
Here is the relevant change to my controller: https://github.com/mjm/sis-lunch/commit/930ced467a0e23ad48f4497999183112c5f846b1#diff-2
Is there something I'm missing? What could be wrong with it in production on Heroku that could cause this to silently fail?
I'm not sure how you are testing it on your development machine, since PeopleControllerTest is empty, but the password field is protected against mass assignment. It shouldn't work in PeopleController the way it is written. (that's a good thing!)
You will need to explicitly call Person#password= in your controller.
The relevant Rails source code for ActiveModel::SecurePassword can show you exactly what happens when you use has_secure_password.
I believe I figured it out. I deployed the app to Heroku, then ran the migrations. The app was not fully aware of the new password_digest column, but new consoles were, so they worked fine. Restarting the app using heroku restart fixed it.

Resources