How to modify Rails middleware to serve gzip assets from Heroku? - ruby-on-rails

My question is closely related to "any way to serve gzip assests from Heroku"
The best approach points to a Gist: https://gist.github.com/2152663
So, how do I make it work? It seems obvious for the person who asked, but I'm having a hard time putting it together.
I understand I have to place compressed_static_assets.rb into /lib and then reference it from my production.rb, but I keep getting the error: "uninitialized constant Middleware (NameError)"

This might be an older question but did you try the heroku-deflater gem? Looks like it does the same thing but is easier to get up and running.

Related

Random "Uninitialized Constant" errors in staging/production

Like many Rails applications, we have a few classes we define in the lib/ folder. We make sure to let Rails know about them in the config/application.rb file like so
config.autoload_paths += Dir[Rails.root.join('lib'), Rails.root.join('lib', '**')]
And that has worked perfectly up until now with no problems. However recently we have been getting random occurrences of "Uninitialied Constant" errors in staging/production. Most of the times things work fine, it's just every once in a while that things break down. Opening a Rails console and the classes are always there.
I tried to better understand how Rails does the autoloading magic, so I read this great article: http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/, but nothing in it helped me.
I also tried a few things that I thought might work, like requiring all the files individually in an initializer, but nothing worked.
I'm using Ruby 2.1.1, Rails 3.2.19, Phusion Passenger 4.x. Anything else that might help? How might Constants become undefined or inaccessible from somewhere? Maybe a gem is messing with the way Rails modifies constant lookup...
Update: I have not enabled threadsafe mode

Ruby on Rails - using modules from a different directory

This is a very basic question, but I can't find exactly the answer I need.
I have the following code in trunk/app/models/parsers/my_file.rb in my dev environment:
def initialize
...
#logger = Utils::SingletonLogger.get_logger
#logger.debug("Instantiating my_file object")
end
It runs fine.
But when I deploy it to the test environment (all code should be identical, but I'm not sure where to start looking for differences if there are any), Rails complains that it can't find Parsers::MyFile::Utils. The Utils module I want to use is in app/lib/my_utils.rb. This makes me think that Rails is creating some sort of namespace for the code in the parsers sub-directory, and only looking there for the Utils module, but I haven't been able to figure out how to make it work for me. Is there some main, application level prefix I can use to specify to look outside of the current directory structure?
I've tried adding require 'my_utils' and require_relative '../../../lib/my_utils.rb'. The former can't find the file, the latter just throws the same error as when I don't have any require at all. I'm not sure if I should have to require this or not.
In any case, I clearly don't quite understand how to refer to code in modules in a different directory, I don't understand when/why rails needs an explicit path at some times/environments but not others, and I don't know how to make Rails look outside of the current file for code. Any help with any of these would be appreciated.
Oh, I'm using Ruby 1.9.3, and rails 3.2.1.
Edit: It just started working, without any changes to the application.rb or environment files. It doesn't even have a require in the current version. Is there any obvious reason for it not to work at first, then to work after another server restart? (I'm pretty sure I restarted it after the code went in - I don't think I just forgot to do that before.)
Anyway, thanks for your help - I really do appreciate it.
You can manually add directories you want to include in application.rb. Might want to make sure in your application.rb or test.rb config files you have this autoload_paths in there, yours might be specific to your development.rb file.
config.autoload_paths += %W(#{config.root}/lib/)

How to get rid of postgresql but still use ActiveRecord::RecordNotFound on heroku when using mongohq?

Edit:
How to use ActiveRecord::RecordNotFound exception to make Rails respond with the standard 404? The basic approach suggested in many places is to modify the config/application.rb to not require "rails/all", but instead check out the file: railties/lib/rails/all.rb and pick and choose what you want/need. However, if you just leave out the part a about active_record, then you can't use ActiveRecord::RecordNotFound (and apparently using fixtures might have problems too, I wouldn't know as I don't use them). How to solve this problem?
The old explanation of the problem is not very relevant but, I'm leaving it here for reference and context for the comments below..
Old explanation:
So here's the deal. We have a Rails app that uses MongoHQ as it's database. Locally thing's run smoothly without any problems, but on production and staging environments it seems that Heroku insists that we must have postgresql database and gems setup/installed. I've tried to delete the addons and related config variables, but it just wont do. This is rather annoying as now the free postgresql causes problems because if we crank up the dynos it will very quickly run out of connections (20 connection limit). However, upgrading to a more production level tier of postgresql seems like a very silly thing to do when the database has 0 tables. How are everyone else using MongoHQ managing this? I can't seem to be able to find any anything about it though I would have thought it to be an apparent issue that everyone using MongoHQ and Heroku would face?
The key idea is that we can still require "activer_record", but lets just leave out the corresponding railtie. This is what I ended up putting into my config/application.rb
require "rails"
frameworks = %w(action_controller action_mailer active_resource rails/test_unit)
frameworks.each { |framework| require "#{framework}/railtie" }
# For errors like ActiveRecord::RecordNotFound
require "active_record"
Credits for the idea goes to mr. Benjamin Oakes:
http://www.benjaminoakes.com/2011/09/15/activerecordconnectionnotestablished-in-rails-3-1-on-heroku/

Proper way to use a Rack middleware from a gem in a Rails project with Bundler

I've got a Rails project that's setup using Bundler. One of my bundled gems provides a Rack middleware that I'd like to use in my Rails app (but only in the 'production' Rails environment).
If I just put something like this in config/environments/production.rb, I get an unknown constant error:
config.middleware.use ::Rack::MyMiddleware
... presumably because Bundler.require has not yet been called at this point, and none of my bundled gems are available.
I have found a few ways of working around this, but none seem great, and I'm wondering if there's a more standard solution that I'm missing:
Explicitly require 'my_middleware_gem' in config/environments/production.rb
Wrap the config.middleware.use call in an after_initialize block, ensuring that Bundler has a chance to do its thing before I try to reference the constant.
Use a string ("::Rack::MyMiddleware") instead of the bare class constant. This doesn't seem to work with Unicorn for some reason, but does work with some other servers (with Unicorn it ends up trying to call "::Rack::MyMiddleware".new, which of course fails).
Am I missing some better approach? At what point in the initialization process is it expected that bundled gems should be available?
Copying the answer from the comments in order to remove this question from the "Unanswered" filter:
matt suggested:
I think using the after_initialize block is the right way in this case.
grumbler confirmed:
Yeah, that's what I ended up going with. Thanks! Regarding the unicorn issue alluded to in the original question, turns out I was hitting this problem: http://davidvollbracht.com/blog/headachenewunicorn-capistrano-bundler-usr2

Newbie help with Rails/Ruby. Totally lost! (Mongrel related, I think) 503 Errors

I am on the verge of actually hiring someone to fix this
for me, but I hope it doesn't come to that.
I have no experience with Rails/Ruby, but I do know my way around
computers in general.
I have two domains on one server (Hostingrails, I am beginning to hate
them more and more these days).
My secondary domain works 100% fine.
But for the past few days, my primary domain has not been working, it
has been giving me 503 Errors. I've opened a ticket regarding this, and
they told me to SSH into my server and reset "Mongrel". I've done this
using the code they gave me; "mongrel_rails start -d -e production
-p13930"
It seemed to have worked, but the problem was still there. The log says
the error is something about:
"require': no such file to load -- dispatcher (LoadError)"
I've re-opened a ticket concerning this, and Hostingrails basically told
me that it is not their problem anymore and that it's solely up to me to
fix it. Brilliant.
So I spent a good part of the day looking and changing things around
through SSH (probably wasn't the greatest idea) but I still keep getting
503'd on my website.
However, I recently found out that my index file HAS to be index.html,
or it will not render the page. index.htm or index.php will result in a
503. If I set the index page to index.html, it worked. Which is strange,
my htaccess file allowed for all.
Another problem, I think I have inadvertently changed something in my
settings while I was SSH'd in. When I do "bundle install" it installs
the gems into my own private webspace, for example /home/mywebsite. But
I believe on my shared plan, all the rails/ruby/gems etc are all under
/usr/local/rvm/gems/ruby-1.9.2-p0/ which I don't think I have access to.
How do I change the directory to the default one? For example, before
the error log said:
/usr/local/rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in
`require': no such file to load -- dispatcher (LoadError)
Now it says:
/home/mysite/.gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in
`require': no such file to load -- dispatcher (LoadError)
I think that's everything for now. Here are the rails installed on my
server by the host:
Installed at (3.0.0): /usr/local/rvm/gems/ruby-1.9.2-p0
(2.3.8): /usr/local/rvm/gems/ruby-1.9.2-p0
(again, I think my mongrel is looking in the wrong place, as my gems are
now being installed into /home/mywebsite/ instead of
/usr/local/rvm/gems/) Is it possible to someone reset the settings I've
changed back into my host's default one?
Would anyone be willing to take the time and try and fix this with me? I
am pretty annoyed at Hostingrails, since I didn't do anything to create
this problem, and they are outright refusing to help me. Why is my
primary domain getting 503 errors when my secondary domain works fine?
Mongrel is not compatible to ruby 1.9.2. You need use a fork of mongrel to use it https://github.com/kyusik/mongrel_cluster
I advice you to user thin/passenger or unicorn instead of mongrel.
I found a little blog post about problem with Mongrel and ruby 1.9.2 http://xaop.com/blog/2010/08/04/deploying-rails-3-on-ruby-1-9-2/
Maybe you could try using Ruby 1.8.7 - it causes less trouble in general at this time.
Not an answer to your question in particular, but if you're new to Ruby and Rails, then hosting your own stuff can be a daunting task.
Instead, try Heroku - simply push your Rails app to Heroku with git and you're good to go. They support custom domainnames for free.

Resources