Rails Model Not Updating on Capistrano deployment - ruby-on-rails

Alright so I've spent considerable amount of time with this and still can't find out what's wrong.
Here's whats going on: I've got a model reward.rb with a method X like this:
class Reward < ActiveRecord::Base
def x
puts "foo" # Method does something...
end
end
The rails app is now on a production environment, in development, if you do
rails c
and then
>> r = Reward.new
>> r.x
"foo" # I.e it works...
now, if you go into the server and do
rails c
and then
>> r = Reward.new
>> r.x
NoMethodError: undefined method `x' for #<Reward:0x0000000561fa08>
If you check reward.rb in the same server you'll see the method's there, actually it's the first method in the file... so, as I can see Rails is not loading the latest code of the model when it loads the console...
I thought it might have something to do with Rails' cache but production.rb says:
MyApp::Application.configure do
config.cache_classes = false
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = false
# SMTP settings and other stuff.. not related to caching...
end
And environment.rb:
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
MyApp::Application.initialize!
And application.rb:
module MyApp
class Application < Rails::Application
config.encoding = "utf-8"
config.filter_parameters += [:password]
end
end
So I've ran out of ideas... The app was deployed with capistrano, I'm using Rails 3.0.10.
UPDATE
Alright, so I figured out the problem, pretty silly to be honest, there was a models.bak folder inside app/ that someone created, on production the models were getting picked up from that folder

Have you run database migrations on your deploy server?
You may need to set up a capistrano recipe to do this. I believe an out-of-date database schema could cause this error.

A stupid question: have you checked the reward.rb file on the server? Is it the correct (new) version?

Try to restart unicorn o what ever you have manually.

you have to do rails c production in order to run the production environment.

Related

NameError: uninitialized constant on Heroku

I have a Rails 5 application with some modules/classes located under /lib. In development I can access those through the rails console like so:
irb(main):001:0> MyClass.do_something
In Production on Heroku I get this:
irb(main):001:0> MyClass.do_something
NameError: uninitialized constant MyClass
As you might have guessed I autoload the /lib directory in my application.rb:
config.autoload_paths << Rails.root.join('lib')
However, the most curious thing about this is, that I can access this class from rake tasks. So something like this works fine:
task do_something: :environment do
MyClass.do_something
end
Which tells me that the class is present on Heroku.
Any ideas?
Rails doesn't autoload in production for thread safety, instead eager loading application constants. You can fix your issue by using the eager_load_paths method instead.
config.eager_load_paths << Rails.root.join('lib')
If you still want to autoload in development you can make it conditional
load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
config.public_send(load_path_strategy) << Rails.root.join('lib')
If you really need autoloading of this directory in production you can set enable_dependency_loading to true.
config.enable_dependency_loading = true
config.autoload_paths << Rails.root.join('lib')
See this blog post for more explanation.
I have been puzzled why all of my objects were uninitialized constant in console on heroku in production. In my local production, they were fine.
Turns out that the problem was that I was running: "heroku run console" not "heroku run rails console".
Worth noting that when you access console from the heroku website, the same problem occurs there too. Wasted a lot of time on this.

Why am I getting an Application Error error page for my brand new app hosted by Heroku?

I am pretty much brand new to RoR and such.
I am following a video tutorial to build my own web-based app, and I got to the step:
git push heroku master
When in git bash, it was coming up with an error that claimed it couldn't compile ruby. Now, it says it is launched and deployed, but there is still the same error on the page for my app, http://infinite-mountain-6131.herokuapp.com/
Any ideas?? I can add files if needed.
Requested file(s):
app/config/application.rb from my comment
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# config/application.rb
config.assets.initialize_on_precompile = false
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Myrubyblog
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.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
end
end
Line 6 that was mentioned in my error is the config.assets.initialize which I put in there with line 5 as suggested to fix my problem.
This is what happens when I run the migrate as suggested (heroku run rake db:migrate)
Running 'rake db:migrate' attached to terminal... up, run.6274
rake aborted!
NameError: undefined local variable or method 'config' for main:Object
/app/config/application.rb:6:in '<top <required>>'
/app/Rakefile:4:in 'require'
/app/Rakefile:4:in '<top <required>'
<See full trace by running task with --trace>
As a rule, there are two types of error you can get when hosting a Rails app on Heroku:
Heroku Error
-
Rails Error
--
Error
The difference between the two is important - rails errors will only occur if your operating environment is actually "running" your Rails application. Heroku errors will occur if your operating environment / Heroku will not load correctly
The problem you have is definitely a Heroku issue - one which is typically created by a lack of db connectivity. The way to fix this issue is to ensure your application has all the necessities to run - most notably the correct db
You'll be best using the following:
$ heroku run rake db:migrate
However, I appreciate this won't be the only issue you'll have
Heroku Deployment
As you've said you're a "beginner" to ROR, let me give you some ideas
Firstly, when you write a question on here, it helps to divulge as much information as possible - typically from the logs, or any other specific error handling mechanism
Secondly, you want to ensure that everything required to get your application running has been achieved. Most notably, when you mention Heroku cannot compile the Ruby application, you'll need to provide information on why this is the case -- there'll probably be a gem conflict (SQLite3) or similar
Thirdly, you need to ensure you have migrated your database. This is the single biggest reason why "Heroku errors" appear - deploying your Rails app doesn't mean the migrations you made locally will persist - you need to ensure you have the db updated as you require, which can be done as follows:
$ heroku run rake db:migrate

Getting a NameError when I run the command rails server

I'm new to Ruby and am following the Michael Hartl's tutorial. I'm still on chapter 1.
It says
undefined local variable or method 'first_app' for main:Object (NameError)
which is in my development.rb line 1.
Firstapp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
I followed other questions on StackOverflow with no solution. Some of them require to changed my app name from
Rails.application.configure do
to
First_app::Application.configure do
which didn't resolve anything. Oh and if it helps, I'm using Windows.
When you ran the rails new command it should have properly set your app's name. I think what happened is you probably ran rails new firstapp instead of rails new first_app. ChangeFirst_app::Application.configure do to FirstApp::Application.configure do. You should also probably do a search in your project for Firstapp or First_App and change those as well.
It had something to do with my Gem file apparently. I didn't edit it this and left it alone, the application ended up compiling without any errors. I think it has something to do with SQLite3 gem that I'm not properly doing something regarding version.

Loading initializers during assets precompile

I am trying to precompile the assets while deploying to production environment. I am also trying to automate it for first time installation on a server using capistrano. It looks like none of the initializer's are getting loaded during the assets precompile process.
I am facing these two problems
For the first time installation I am generating a initializer file(initializers/freshinstall.rb) on the fly with the below content
config.assets.initialize_on_precompile = false
so that precompile doesn't check the database which doesn't exist yet
I also have some vendor files, and their locations are set in the asset pipeline, and are placed in separate initializer file initializers/vendor.rb
MyApp::Application.config.assets.paths << "#Rails.root}/vendor/assets/images/xxxx" << "# {Rails.root}/vendor/assets/images/xxxx/helpers"
MyApp::Application.config.assets.paths << "#{Rails.root}/vendor/assets/stylesheets/xxxx"
MyApp::Application.config.assets.paths << "#{Rails.root}/vendor/assets/stylesheets/yyyy" << "#{Rails.root}/vendor/assets/images/yyyy"
When capistrano runs the assets precompile task, its not able to find the vendor paths or stopping it from looking into the database. This brings me to a conclusion that the initializer's are not getting loaded. After going through some stackoverflow questions. I even added a railtie to config/application.rb
module AssetsInitializers
class Railtie < Rails::Railtie
initializer "assets_initializers.initialize_rails",
:group => :assets do |app|
require "#{Rails.root}/config/initializers/freshinstall.rb"
require "#{Rails.root}/config/initializers/vendor.rb"
end
end
end
But I still don't see any initializers getting loaded. Can I get some info on the internals of the boot process of an rail application, and also why the initializers are not getting loaded during the assets precompile process.
Some documentations would be really helpful to understand this. The Rails documentation is very minimal with respect to railtie and the initializer method.
http://guides.rubyonrails.org/configuring.html
Thank you in advance
Finally was able to figure out how to do it. This works for my single server capistrano deployment. Below is the capistrano task for my new_deploy on to a fresh server.
set :fresh_install, false
task :new_deploy do
set :fresh_install,true
deploy.setup
#The assets:precompile process is part of the deploy.update. Before the precompile process, we will create database.
deploy.update
deploy.migrate
run_seed
#load unicorn server
end
Dont do any configuration setting mentioned below
config.assets.initialize_on_precompile = false # no need of this in application.rb
Instead just before assets:precompile create your database
before "deploy:assets:precompile" , "yourapp:create_database"
See that you check if the fresh install flag is set, then only create the database.This method will also be called during regular deploy when ever you are updating the server with latest revision. During that scenario fresh_install flag will be false.
desc 'Create a new database'
task :create_database, :roles => :app do
if fresh_install
run "cd #{release_path}; bundle exec rake db:create RAILS_ENV=#{rails_env}"
end
end

How to run my ruby code after Rails server start?

I tried:
after_initialize do
#code
end
But: (documentation)
Some parts of your application, notably observers and routing, are not
yet set up at the point where the after_initialize block is called.
I need routing and logger in my code
Any ideas?
See section 3.1 from http://guides.rubyonrails.org/configuring.html
I believe you would put this code in config/application.rb
config.after_initialize do
# ....
end
# config.after_initialize takes a block which will be run after Rails has finished initializing the application.
# That includes the initialization of the framework itself
Also http://guides.rubyonrails.org/initialization.html
#house9's answer is correct, as pointed out by the comments, this will also execute when running rake tasks, console, etc. I used the following to recognize when a server was actually being executed:
# application.rb
if defined?(Rails::Server)
config.after_initialize do
# Do stuff here
end
end
Another option is to create a custom initializer. It's just a ruby file that lives under config/initializers/ and is executed exactly "on_server_start" event :)
Lines added to config.ru will be run by the Rails server, but not by Rails console or Rake tasks that load the environment.
# config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path("../config/environment", __FILE__)
# your code here (after environment is loaded)
run Rails.application
Since Rails 5 the default server is Puma, so code in config/puma.rb will be run just once, and only if the server is started.

Resources