Ruby on Rails: Active Admin and Heroku - dashboard error - ruby-on-rails-3

I have some Ruby on Rails applications that are using Active Admin gem. Rails version is 3.2.6, Active Admin version is 0.4.4.
I am pushing these applications to Heroku, then doing migrations and everything is working fine. But after some time (when application restarts) i'm starting to get 404 error when trying to open admin page (like myapp/admin). In logs there is an error:
ActionController::RoutingError (uninitialized constant Admin::DashboardController)
Moreover, if i'm trying to open some other admin page (like myapp/admin/videos - to administer videos) everything is still working fine, but error 404 persists when opening Dashboard page.
I have tried to put
config.cache_classes = true
config.assets.compile = true
to my config files, but all the same.
Basically the scheme is as follows:
I make some changes to the app, commit the changes with "git add .", "git commit" and push it to Heroku
I open the /admin page on Heroku and it works fine
After application restarts i get 404 error when visiting /admin, but everything still works when accessing other admin pages, not dashboard
GoTo 1
I'm still unsure if the error appears when the app is restarted by itself (not by "heroku restart").
Any ideas why this is happening? Maybe someone can advice how to switch off this Dashboard and use my myapp/admin/videos as the default admin page?

I had this very same problem, and since it complaints about the ActiveAdmin Dashboard, and it is now deprecated I proceeded to update my dashboard.rb file to the new Dashboard style and that solved the problem.
(I got that file from here).
Hope it helps.

I got the same issue.
Check whether you have to upgrade ActiveAdmin to new version
When upgrading to a new version of ActiveAdmin you may need to run
rails generate active_admin:assets
If you get:
uninitialized constant Admin::DashboardController
Use the New default page for admin/dashboard.rb
which is like following,
ActiveAdmin.register_page "Dashboard" do
menu :priority => 1, :label => proc{ I18n.t("active_admin.dashboard") }
content :title => proc{ I18n.t("active_admin.dashboard") } do
div :class => "blank_slate_container", :id => "dashboard_default_message" do
span :class => "blank_slate" do
span I18n.t("active_admin.dashboard_welcome.welcome")
small I18n.t("active_admin.dashboard_welcome.call_to_action")
end
end
# Here is an example of a simple dashboard with columns and panels.
#
# columns do
# column do
# panel "Recent Posts" do
# ul do
# Post.recent(5).map do |post|
# li link_to(post.title, admin_post_path(post))
# end
# end
# end
# end
# column do
# panel "Info" do
# para "Welcome to ActiveAdmin."
# end
# end
# end
end # content
end

Related

ActionMailer sending real emails in test mode! - How to turn off?

Newly signed up users to my little app must be approved by the admin (me) before they can gain access to the site. I've succeeded in generating such emails in development with an after_create :send_admin_email in my user model which works great. My problem is that I'm generating multiple users during my tests (using FactoryGirl) and each test user created sends off a real email. Running my tests is like pouring molasses in January and I've got to delete hundreds of emails sent to my inbox. How do I turn that off?
Action Mailer Basics in the Rails Guides tells me that "By default Action Mailer does not send emails in the test environment. They are just added to the ActionMailer::Base.deliveries array."
Moreover, in config/environments/test.rb I've got:
config.action_mailer.delivery_method = :test
That's in addition to in config/environment.rb having:
# Configuration for using SendGrid on Heroku
ActionMailer::Base.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => '587',
:authentication => :plain,
:user_name => 'app[my app number]#heroku.com',
:password => '[something super secret]',
:domain => '[let's get this party started!.com]',
:enable_starttls_auto => true
}
ActionMailer::Base.delivery_method = :smtp
I'm sure that I'm missing something simple and basic. I've searched around and related questions and posts deal with how to test that ActionMailer actually sent email.
Humble gratitude in advance for any thoughts or help.
Addendum: Following answer to similar question found at Is it possible to turn off ActionMailer emails when cucumber testing is happening on development? I was able to stop the email sending madness. Still, I had to add ActionMailer::Base.delivery_method = :test to several rspec files. Is there a way I can shut this down globally? Anyone have any thoughts on what's going on?
So I've figured it out. Having the line ActionMailer::Base.delivery_method = :smtp in config/environment.rb overrides ActionMailer::Base.delivery_method = :test in config/environments/test.rb.
So, delete that line, ActionMailer::Base.delivery_method = :smtp'
from config/environment.rb and place it in config/environments/production.rb.
That allows you to place ActionMailer::Base.delivery_method = :test in config/environments/test.rb and the version you want in config/environments/development.rb. I made development.rb :test as I populated my database using Faker and changed it to smtp so I was sure that real emails were sent as an additional check.
Note: You must restart your server for these changes to take effect.
Another note: Heroku's current SendGrid Instructions put the SendGrid Heroku configuration code in a new config/initializers/mail.rb file which will likely require removing its last line and placing the desired version in each config/environments/[production.rb, development.rb, test.rb]
Perhaps useful...
My config/environment.rb did not contain ActionMailer::Base.delivery_method = :smtp and my config/environments/test.rb did contain ActionMailer::Base.delivery_method = :test but Rails still delivered mailers while testing.
I simply added the following to config/environments/test.rb to fix:
config.action_mailer.perform_deliveries = false
I faced the similar situation in Rails4.2 (ActiveJob integration with ActionMailer) even if I didn't write delivery_method = :smtp in config/environment.rb.
In my case, The issue here happened after using "resque" as background worker. Finally, I found out that the following config was WRONG:
config/initializers/active_job.rb:
Rails.application.config.active_job.queue_adapter = :resque # here is WRONG
...because it effected to test mode as well.
So, I set "queue_adapter = :resque" only in config/environments/{development,production.rb}. Now, that works as I expect.

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)?

Rails console log - how to customize what is printed in the console

When I run rails s it loads up and everything works. When I browse to a page several lines of information are printed. Mostly this is the webpage getting the assets for the page. I really don't need to see this and have it clutter my screen. Is there a way to customize what gets printed in console?
Thanks
For assets pipeline messages it seems that you can't (yet). See How to disable logging of asset pipeline (sprockets) messages in Rails 3.1? and the rails issue on Github
You can do it in part by using these lines (credits) in your development.rb file
config.after_initialize do |app|
app.assets.logger = Logger.new('/dev/null')
end
For Rails 3.1, inside config/environments/development.rb, set the following to false:
config.assets.debug = false
Your logs will show you everything you want to see minus the assets.
You can configure the logging detail of the rails dev server by setting config.log_level in environments/development.rb. Setting it to :warn will get rid of most of the logging (you can always send your own messages with whatever log level you want so they still get printed).
http://guides.rubyonrails.org/debugging_rails_applications.html#log-levels
http://guides.rubyonrails.org/debugging_rails_applications.html#log-levels

Rails, Capybara and subdomains: how to visit certain subdomain

Rails 3, Cucumber 0.9.4, Capybara 0.4.0
I want to test my features with subdomain. I found that solution:
Given /^I visit subdomain "(.+)"$/ do |sub|
Capybara.default_host = "#{sub}.example.com" #for Rack::Test
Capybara.app_host = "http://#{sub}.example.com:9887" if Capybara.current_driver == :culerity
end
It works if I run cucumber features/subdomain.feature but it fails if I run cucumber features! It's unbelievable, but it's true. I logged current urls and it is subdomain.example.com for cucumber features/subdomain.feature and www.example.com for cucumber features for one scenario with
Scenario: subdomain scenario
Given I visit subdomain "subdomain"
in both cases!
I don't know the reason...
Is there best way for testing subdomains with capybara?
Okay, here is what should be a fairly straightforward and easy to understand hack of Capybara that yields the desired behavior, namely to be able to create a new session each time you switch subdomains. This is useful for sites where a user registers on one domain (which results in a subdomain being created for his account) and then ends up needing to navigate over to that subdomain.
First of all (and this part is fairly common to the other solutions out there) go ahead and give yourself a way to change Capybara.default_host in a Cucumber step. I did it like this:
Then /^I switch the subdomain to (\w+)$/ do |s|
Capybara.default_host = "#{s}.smackaho.st"
end
Stick this step into your Cucumber feature at the point where you want the new subdomain to be used. For example:
When I open the email
Then I should see "http://acme.rightbonus.com/users/confirmation" in the email body
Given I switch the subdomain to acme
When I follow "Click here to finish setting up your account" in the email
Then I should be on the user confirmation page for acme
Now for the magical monkeypatching that makes this work. Basically, you want Capybara to be smart enough to detect when the subdomain has changed and reset its RackTest session object.
# features/support/capybara.rb
class Capybara::Driver::RackTest
# keep track of the default host you started with
def initialize(app)
raise ArgumentError,
"rack-test requires a rack application, but none was given" unless app
#app = app
#default_host = Capybara.default_host
end
def process(method, path, attributes = {})
reset_if_host_has_changed
path = ["http://", #default_host, path].join
return if path.gsub(/^#{request_path}/, '') =~ /^#/
path = request_path + path if path =~ /^\?/
send(method, to_binary(path), to_binary( attributes ), env)
follow_redirects!
end
private
def build_rack_mock_session # :nodoc:
puts "building a new Rack::MockSession for " + Capybara.default_host
Rack::MockSession.new(app, Capybara.default_host || "www.example.com")
end
def reset_if_host_has_changed
if #default_host != Capybara.default_host
reset! # clears the existing MockSession
#default_host = Capybara.default_host
end
end
end
This patch works with Capybara 0.4.1.1 and will probably not work with different versions unless modified. Good luck.
If your needs don't include anything to do with sessions, and all you're after is visiting a different subdomain, I wrote this function:
def visit_with_subdomain(uri, options = {})
domain = Capybara.default_host
port = Capybara.server_port
subdomain = options[:subdomain]
visit "http://#{subdomain}.#{domain}:#{port}#{uri}"
end
You can call it like this:
visit_with_subdomain some_path, subdomain: some_subdomain
Had the same problem for a bit with and my test had to sometimes switch or redirect back and forth between subdomains.
given this step:
When /^(?:|I )go to "(.+)"$/ do |url|
visit url
end
When I go to "http://mysubdomain.example.org" works in rack test, but if you are redirected by the app or follow a link to some other path the host reverts to the default_host.
There's a fork of rack-test by hassox that ensures that rack-test keeps track of the host used in the previous request.
So, in my Gemfile, before requiring capybara:
gem 'rack-test', :git => "https://github.com/hassox/rack-test.git"
Now if I need to hit a particular subdomain (or the app redirects me to one, like secure.myapp.com/sign_in) I'm sure that the feature can read more like a browser would behave: it will allow me to stay on the current subdomain until I go–using capybara's visit("somesubdomain.example.org")–or am redirected by the app to a different host.

ruby on Rails 3 and routing

I am new to rails and have been working thru a number of tutorials. I have a controller with the following actions: Contact and Home. The routes.rb has the following:
SampleApp::Application.routes.draw do
get "pages/home"
get "pages/contact"
# The priority is based upon order of creation:
# first created -> highest priority.
Everything else in the standard routes is commented
When I try to reach the page http://localhost:3000/pages/home
I get
Routing Error
No route matches "/pages/home"
on the web page.
I restarted the rails server and checked routes with rake routes - results below
pages_home GET /pages/home(.:format) {:controller=>"pages", :action=>"home"}
pages_contact GET /pages/contact(.:format) {:controller=>"pages", :action=>"contact"}
I tried other tutorials that were based on 2.3 version of rails and had lots of routing issues but was running 3.0 instead so went to 3.0 tutorial. Same routing issues. I even have the same problem when I put a static page "hello world" in the public folder. According to tutorial, that should just come up but I get same routing error message.
Any suggestions would be most appreciated.
I solved my problem. A real noob mistake. Running rails, it is important to be in the right directory. I was in a previous example directory so the routes I needed were not there.