How do you configure MongoMapper 0.11 with MONGOHQ_URL? - ruby-on-rails-3

I want to run MongoMapper on Heroku. This necessitates MongoHQ. All the documentation, like http://mongomapper.com/documentation/getting-started/rails.html, tells you to create an initializer to connect to Mongo with the MONGOHQ_URL environment variable. However, recent versions on MongoMapper don't require an initializer, it just connects automatically now based on the content of config/mongo.yml.
Here inlies the problem: mongo.yml doesn't seem to allow me to connect with a URL, only with host, port, etc. I tried the following and it didn't work for me:
production:
url: <%= ENV['MONGOHQ_URL'] %>
Any other ideas on how to get this working?
(the error I get when deploying to heroku is that the app is trying to connect to localhost:27017 and failing.)

Wait I figured it out...
production:
uri: <%= ENV['MONGOHQ_URL'] %>
(uri, not url)

Related

Heroku mongo_mapper MONGOHQ_URL unparseable by ruby uri

I have scoured the Internet without finding an adequate solution, so I'm here to ask the SO community for help.
I'm migrating a rails 2 app on Heroku Bamboo to Cedar. Concomitantly, I am moving to rails 3 and ruby 2.0.0 (though I get this error with ruby 1.9.3 as well).
It seems that MongoMapper has undergone a bit a change from 0.8.6, to the point where I can't use our old initializer anymore. I'm attempting to use the latest 0.13.1 version of mongo_mapper.
According to https://devcenter.heroku.com/articles/mongohq, I just need to set config/mongo.yml to:
production:
uri: <%= ENV['MONGOHQ_URL'] %>
and I'm all set (I also commented out the old initializer code). However, it fails with the following connection error:
Feb 05 11:18:28 my-app-name app/web.1: /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize': the scheme mongodb does not accept registry part: heroku:2QMdYzo6z5nmJJsmWAWKd_205umc05tBuP2ZodGaNDZ7N5rE4ns09jhsfFBjmkQ2ls_rfTiVC0lD24Y2byDXbg#candidate.21.mongolayer.com:10499,candidate.4.mongolayer.com:10625 (or bad hostname?) (URI::InvalidURIError)
An invalid URI is understandable, but that's what being fed to me by Heroku. What do I am missing in order to for the uri parser to accept it?
Thank you in advance.
The answer lies in the presence of that comma (,) in the uri. When I removed the second host and the comma, it behaved correctly :-)
Specifically, I created a Heroku ENV variable called MONGOHQ_URL2 without the second host name, then updated my config/mongo.yml to use that one instead.

Setting host/remote_addr and other env properties in Rails 3 controller tests

In Rails 2, you could specify the host and other Rack env properties in controller tests like so:
should "spoof host and remote_addr" do
get "/thing/2", {}, :remote_addr => "192.71.1.2", :host => "somewhere.else"
end
However, for some reason this is not working out on Rails 3. I tried with a regular controller, and env["HTTP_HOST"] isn't being set as expected (same with "REMOTE_ADDR"). I also tried this:
should "use host and remote_addr" do
request.env["REMOTE_ADDR"] = "192.71.1.2"
request.env["HTTP_HOST"] = "git.gittit.it"
get "/thing/1"
end
This also used to work in Rails 2, but no longer in Rails 3. As a final test, I tried this with a route that resolved to a bare Rack app, same results.
How can I spoof the host and IP address in a Rails 3 controller test?
Depending on how you're accessing it in the controller... this has worked well for me:
request.stub!(:remote_ip).and_return('192.71.1.2')
At which point when I use request.remote_ip in my controller, I get 192.71.1.2

Heroku is driving me nuts! Is my code amazingly sloppy, or is Heroku amazingly picky?

wow. going super nuts here trying to deploy to staging on heroku cedar from Rails 3.2.2. I've gotten everything to work, but I wanted to run these issues up the flagpole to see if there's something wrong with... me. eheh
Both of these issues give me the not-helpful "We're sorry, but something went wrong." error page. So it was frustrating when I had 2 different issues (that acted like 3) in one deploy (that worked fine on my local).
Heroku won't give me my logs.
when I run
heroku logs
I get a long error message that starts with,
c:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:762:in `initialize': Permission denied - connect(2) (Errno::EACCES)
so i've been doing all this troubleshooting via small slices of commits. maddening.
Heroku chokes when it can't find an image with image_tag
this works on heroku:
= image_tag("content/portfolio/maskphoto_rubble_rebel_blur.jpg", :alt => params[:photo], :width => "100%")
This doesn't (only difference is an extra letter in the file name, though it works on my local):
= image_tag("content/portfolio/maskphoto_rubble_rebell_blur.jpg", :alt => params[:photo], :width => "100%")
Am i nuts in thinking that heroku should just serve up the image tag as-is and let it just not display, rather than crashing the entire page? I'm running compass; not sure if that has anything to do with anything.
Heroku hates nested expressions in an array ref
this works:
n = f.index(params[:photo]) +1
#nextphoto = f[ n ]
this doesn't (but does on my local):
#nextphoto = f[ f.index(params[:photo]) +1 ]
i guess it's better form to separate expressions, but still. why would it work on my local and not on deploy?
I can't directly answer all of your questions, but here are a few things to look at:
Heroku won't give me my logs.
The error you are getting indicates Permission denied ... Perhaps your account credentials are not setup properly? I see you are on a windows box ... on a unix machine, the heroku client writes a file at ~/.heroku/credentials with the username and what appears to be an API token. Check to see if you have a similar file. You can also check https://toolbelt.herokuapp.com/windows and make sure you have successfully performed the heroku login command.
Heroku chokes when it can't find an image with image_tag
I don't have many ideas here. Perhaps it is related to the asset-pipeline?
Heroku hates nested expressions in an array ref
This one doesn't make a whole lot of sense either. Perhaps the logs can shed some light here. I did notice that you appear to be running Ruby 1.9.3 on your system, and I don't believe heroku supports 1.9.3 yet. Maybe you have hit a version-specific bug.
I hope that helps. Good luck.

Heroku Cedar: How to scale WEB dynos based on time of day

I want my Rails 3.1 app to scale up to 1 web dyno at 8am, then down to 0 web dynos at 5pm.
BUT, I do not want to sign up for a paid service, and I cannot count on my home computer being connected to the internet.
It seems like the Heroku Scheduler should make this trivial. Any quick solutions or links?
The answer is 'yes' you can do this from scheduler and it's trivial once you know the answer:
Add a heroku config var with your app name: heroku config:add APP_NAME:blah
Add gem 'heroku' to your Gemfile
In order to verify, manually scale up/down your app: heroku ps:scale web=2
Add a rake task to lib/tasks/scheduler.rake:
desc "Scale up dynos"
task :spin_up => :environment do
heroku = Heroku::Client.new('USERNAME', 'PASSWORD')
heroku.ps_scale(ENV['APP_NAME'], :type=>'web', :qty=>2)
end
# Add a similar task to Spin down
Add the Scheduler addon: heroku addons:add scheduler:standard
Use the Scheduler web interface to add "rake spin_up" at whatever time you like
Add a rake spin_down task and schedule it for whenever.
Notes:
Step 1 is needed because I couldn't find any other way to be certain of the App name (and I use 'staging' and 'production' environments for my apps.
Step 3 is required because otherwise the ruby command errors out as it requires that you first agree (via Yes/No response) that you will be charged money as a result of this action.
In step 4, I couldn't find any docs about how to do this with an API key via the heroku gem, so it looks like user/pass is required.
Hope this helps someone else!
Just implemented this approach (good answer above #dnszero), thought I would update the answer with Heroku's new API.
Add your app name as a heroku config variable
require 'heroku-api'
desc "Scale UP dynos"
task :spin_up => :environment do
heroku = Heroku::API.new(:api_key => 'YOUR_ACCOUNT_API_KEY')
heroku.post_ps_scale(ENV['APP_NAME'], 'web', 2)
end
This is with heroku (2.31.2), heroku-api (0.3.5)
You can scale your web process to zero by
heroku ps:scale web=0
or back to 1 via
heroku ps:scale web=1
you'd then have to have a task set to run at 8 that scales it up and one that runs at 17 that scales it down. Heroku may require you to verify your account (ie enter credit card details) to use the Heroku Scheduler plus then you'd have to have the Heroku gem inside your app and your Heroku credentials too so it can turn your app on or off.
But like Neil says - you get 750hrs a month free which can't roll over into the next month so why not just leave it running all the time?
See also this complete gist, which also deals with the right command to use from the Heroku scheduler: https://gist.github.com/maggix/8676595
So I decided to implement this in 2017 and saw that the Heroku gem used by the accepted answer has been deprecated in favor of the 'platform-api' gem. I just thought I'd post what worked for me, since i haven't seen any other posts with a more up-to-date answer.
Here is my rake file that scales my web dynos to a count of 2. I used 'httparty' gem to make a PATCH request with appropriate headers to the Platform API, as per their docs, in the "Formation" section.
require 'platform-api'
require 'httparty'
desc "Scale UP dynos"
task :scale_up => :environment do
headers = {
"Authorization" => "Bearer #{ENV['HEROKU_API_KEY']}",
"Content-Type" => "application/json",
"Accept" => "application/vnd.heroku+json; version=3"
}
params = {
:quantity => 2,
:size => "standard-1X"
}
response = HTTParty.patch("https://api.heroku.com/apps/#{ENV['APP_NAME']}/formation/web", body: params.to_json, headers: headers)
puts response
end
As an update to #Ren's answer, Heroku's Platform API gem makes this really easy.
heroku = PlatformAPI.connect_oauth(<HEROKU PLATFORM API KEY>)
heroku.formation.batch_update(<HEROKU APP NAME>, {"updates" =>
[{"process" => <PROCESS NAME>,
"quantity" => <QUANTITY AS INTEGER>,
"size" => <DYNO SIZE>}]
})
If you're running on the cedar stack, you won't be able to scale to zero web dynos without changing the procfile and deploying.
Also, why bother if you get one free dyno a month (750 dyno hours, a little over a month in fact)?

Deploying rails 3.1 app in subdirectory

I'm trying to deploy my rails 3.1.3 app in a subdirectory on the server:
Apache (reverse proxy) => unicorn (listening on localhost:5000)
The problem is with url_helper.
via the --path switch in unicorn I'm setting my /subdir
It gets picked up by rails; DashboardController.config.relative_url_root gives me that subdir.
But when I use something like 'members_path' in my view it gives me '/members' and not '/subdir/members'
what am I missing?
I had exactly the same problem. Two things were missing/faulty in my setup.
My web-server had an superflous, faiulty rewrite-rule, rewriting /prefix/<controller> to just /controller.
It seems Rails3 routing are by default ignoring relative_url_root. (Stupid IMHO) There's a good tip in https://stackoverflow.com/a/5457484/103192 that shows a trick to make it work again.
Otherwise, you can wrap the run statement in your config.ru with the
following block:
map ActionController::Base.config.relative_url_root || "/" do
run FooApp::Application
end
I now have it working much like one would want it to work.