Creating a Sitemap Automagically for Rails App

Sitemaps help in making sure that your app is properly indexed, so it would help to automatically have them generated (and updated) so a search engine knows when a new web page is created, or an old one updated.  Luckily, there’s a gem, SitemapGenerator that makes it extremely easy to do this.

All you have to do  in Rails 3 is:

  1. add: gem ‘sitemap_generator’ to your gemfile
  2. run “rake sitemap:install” which creates config/sitemap.rb
  3. customize sitemap.rb

A simple example (where “Content” is a model name)

SitemapGenerator::Sitemap.default_host = "http://www.example.com"
SitemapGenerator::Sitemap.create do
  add '/contact_us'
  Content.find_each do |content|
    add content_path(content), :lastmod => content.updated_at
  end
end

4. run “rake sitemap:refresh”

5.  change your robots.txt file (if you have one) to include this line (so search engines can find it easy):

Sitemap: http://www.example.com/sitemap_index.xml.gz

6.  if you’re using Heroku, like me, you’ll have to take extra steps, as in this example, to write the files to somewhere else since Heroku is read-only.

7.  Also, if you’re using Heroku, you may want to use Heroku Scheduler to automatically refresh the sitemap by adding this task:

$ rake sitemap:refresh

8.  Lastly, to make sure Google indexes your site better, you’ll want to enter the path to your sitemap in a Google Webmaster Tools account for your site – the same as the address in step 5, unless you are using Heroku or another read-only system (and the sitemap is stored on another domain).  In this case, since Google Webmaster tools only accepts url’s from your domain (for the sitemap location), you’ll have to re-route them to the external location.  To do that you can make a simple controller like this example from Bill Rowell or you can use the rack-rewite gem.

Making Devise Views Use SSL

I had trouble figuring out the best way to make Devise views secure.  Devise recommends making all pages secure since they use cookies, but I had some views that I could not make secure, so I needed to figure out how to make some views, including the Devise ones, secure.  Normally I would indicate force_ssl in the controller, but Devise is an installed gem that I didn’t want to mess with.

I found the answer after digging awhile, here.

#for Rails 3.1 and above, in config/environments/production.rb
config.to_prepare { Devise::SessionsController.force_ssl }
config.to_prepare { Devise::RegistrationsController.force_ssl }
config.to_prepare { Devise::PasswordsController.force_ssl }

Getting ActiveAdmin to Work on Heroku

The ActiveAdmin gem was working for me in development, but not in production.  The reason, I found, was because not all of the assets used by ActiveAdmin were getting precompiled by Heroku.  To solve the issue, I used the code by Ryan Long’s answer on Stack Overflow (in production.rb).

# Precompile additional assets. Defaults to [application.js, application.css, non-JS/CSS]
config.assets.precompile += ['active_admin.css', 'active_admin/print.css', 'active_admin.js']

Welcome Email After Devise Confirmation

After getting :confirmable working for the Rails Devise gem, I wanted to create a welcome email that would tell the user that they successfully confirmed their account and welcoming them to the site.

Here are the steps I took:

  1. Create the email views and placed them in my mailer directory
  2. I use User.rb as my model, so I created an observer to watch changes to the models.  In that app/models/user_observer.rb, I put this code:

def after_save(user)
# Send Welcome Mail after confirmation
if user.confirmed_at_changed?
Mailer.welcome_mail(user).deliver!
end
end

This watches for the change in confirmed_at, then sends my email (welcome_mail).

3.  In application.rb, added this:

config.active_record.observers = :user_observer

Rails Paperclip Error: identify ‘-format’ ‘%wx%h’

I was receiving the “identify ‘-format’ ‘%wx%h’ ” error with Paperclip.  The reason is because Paperclip requires ImageMagick if images are manipulated, and the path must be specified for this to happen.  In order to find the path in Windows, what I did was:

  1. open a command prompt (CMD from the start menu)
  2. navigate to c://
  3. type “PATH”
  4. it should show the path(s) that can be used for ImageMagick
  5. I added this line to development.rb

Paperclip.options[:command_path] = “/bin” #(in place of “/bin” put your path)

Restart your server.

Inline Link for Field in Simple Form

I needed to put a link to the right of a checkbox on my user sign-up form so that people could view my app’s terms of service and privacy policy before agreeing to it.  I was having trouble figuring out how to do it with Simple_Form, but eventually I was able to figure it out based on this Stack Overflow question.

My final code looked like this:

<%= content_for(:the_links) do %>
  I agree to the <%= link_to "Terms of Service", terms_path,:remote => true %>
  and <%=link_to "Privacy Policy", privacy_path, :remote => true%>
<% end %>

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= f.input :terms, :as => :boolean, boolean_style: :inline, :label => content_for(:the_links)%> 
<% end %>

Sign Out Wasn’t Working with Devise for Me

Devise’s Sign Out wasn’t working for me. I’ve seen other solutions, but they didn’t worked for me. However, I found an answer that worked for me on Devise’s wiki.

Previously, I used this link:

<%= link_to "Logout", destroy_user_session_path, method: :delete %>

However, that wasn’t working, so I changed (in config/initializers/devise.rb in ):

config.sign_out_via = :delete

to:

config.sign_out_via = :get

and revised the link to (removed “method: :delete”):

<%= link_to "Logout", destroy_user_session_path %>

Getting ActiveAdmin to Play Nice with Will_Paginate

My app was already using will_paginate extensively and I didn’t feel like changing it all to the Kaminari which ActiveAdmin uses for pagination.

However, somehow I was able to get it to work by thumbing through this ActiveAdmin issue.  I created the initializer suggested by kml with this code:

Kaminari.configure do |config| 
 config.page_method_name = :bonzo # :) 
end

However, when I implemented it, the code recommended for config/initializers/active_admin.rb caused me errors so I removed it.  You may find that you need this code.