Now I've Got Pretty Permalinks and Much More

Note: This blog post referred to an older version of this blog that I had built from scratch. I've attempted to update links so they don't 404, but know that this post is not currently accurate.

I'm off to a pretty good start with my yearly goals. It may not look like it but I've made a lot of changes under the hood to this blog. I was finding my ability to find myself on google pretty low so I added a sitemap — and it's not just any sitemap, it auto-updates using sweepers. In the next post I'll go over how to build the sitemap specifically.

A couple other new features are "pretty permalinks" and an RSS Feed. For the permalinks I used the Stringex gem. The gem allows you to more easily control your permalinks and comes with a nifty little method that allows you to create the URL's for already existing posts. I then made sure I added rewrite rules to my nginx config so that the old /posts/1 urls still functioned. Nginx rewrite rules are a little different from Apache as you can see in my exmaple below:

rewrite ^/posts/1(/)?$ /posts/hello-world permanent;

Lastly, I updated my 404, 422, and 500 pages to actually look like my site. Yipee!. I should have done that earlier, but when I built eileenbuildswithrails.com I wanted to get it live before the New Year.

Next set of changes will involve adding pages to the cms, including a contact form, ability to add images, and perhaps comments. Thanks for reading!

Categories: tips nifty-methods gems

Setting Goals for the Coming Year

Every year at EMN we do performance evaluations sometime during the summer. Generally, they are pretty straight forward, but a question I was asked got me thinking;

"Where do I want to be in a year?"

Every year I amaze myself with the amount I've learned in the past year. But I've always done so without setting trackable goals where I can actually see my progress throughout the year. I personally find New Year's resolutions to be contrived and most give up because they set goals that don't have manageable steps. Changing oneself – whether that be on a personal or professional level – takes time.

Here are my manageable goals for the year:

  • Make this blog better - mostly under the hood stuff. I am working on currently adding a sitemap , pretty permalinks, rss and fixing up my 400 & 500 pages. Also, want to add photos, pages, comments fleshing out the admin to be more of a CMS that I can distribute on a small scale.
  • Improve the testing on the blog (I have tests but not for everything and I want to get better at TDD by increasing my code coverage)
  • Finish the Ruby Koans to improve my TDD (by the way, Ruby Koans are awesome and I'm about 1/3 of the way to enlightenment)
  • Contribute to at least 2 open source projects and release at least 1 open source project.
  • Continue doing what I'm doing — learning new languages/frameworks, building awesome web applications, I'd like to spend more time with Sinatra, Emberjs, Backbonejs, RubyMotion, etc
  • Don't forget to have fun and ensure I maintain a healthy work/life balance
  • Write more in this blog. I've been writing at least once a month but I can do better since I'm learning new things

So, there you have it. My goals for the year. I'm sure they'll change, but now I can track my progress on my yearly goals.

I encourage you to create your own development goals for the year and at the end of the year determine whether you have reached or exceeded your goals.

Categories: shoutouts updates

:has_many Relationships in ActiveAdmin

When I began using ActiveAdmin I discovered that there is not a lot of documentation on advanced usage such as displaying the :has_many relationships on the index and show page in the admin of the posts. I wanted to make it easy to add categories to posts and to know how posts were categorized easily.

Once the Category and Post models are created a join model also needs to exist, in this case Categorization. This part is the same as any other :has_many, the hard part is display in the admin.

Go into the admin view for Post and add the following (other fields removed for easy viewing):

index do
  column :title, :sortable => :title do |post|
    link_to post.title, [:edit_admin, post]
  end
  
  column :categories do |post|
    table_for post.categories.order('title ASC') do
      column do |category|
        link_to category.title, [ :admin, category ]
      end
    end
  end
  default_actions
end

show do
  attributes_table do
    row :title
    row :content
    table_for post.categories.order('title ASC') do
      column "Categories" do |category|
        link_to category.title, [ :admin, category ]
      end
    end
  end
end

form do |f|
  f.inputs "Add/Edit Post" do
    f.input :title
    f.input :content
    f.input :categories, :as => :check_boxes
  end
  f.buttons
end

As you can see inside the tables creating a special inner table is required for best display. I add the link to the category edit in so it's easy to edit/view the category from the posts table.

To add checkboxes for category select it's as simple as adding f.input :categories, :as => :check_boxes to your form view.

Want to figure out how to set up active admin? Read my "Lots of Love for ActiveAdmin" post. If you have questions, comment on the gist on github or find me on twitter.

ActiveAdmin is a really great simple way to implement an admin for a simple website or blog.

Honeypot for Rails Email Form

While working on my companies new website I realized that our contact form didn't have any spam protection and would become a favorite of bots not long after launch so I decided to add a honeypot.

If you're not familiar a honeypot is a hidden form that users can't see, but because bots don't read CSS they fill it in. If the form is filled in it automatically fails. This is a better alternative to the captcha because it doesn't require your users to type out a ridiculously illegible code (which from experience, i can tell you gets frustrating when you've gotten it wrong 60000 times).

I searched through a few gems and after being frustrated with the outcome decided to just do it myself because really it's just a few fields and the form is ajaxed and the gems would send a 200 response essentially removing the form, which was no my intention.

Open your form view and add a field for the honeypot. Be sure to add a label explaining it is a honeypot to ensure accessibility for screen readers and instructing users to not fill in the field.

<div class="field sweet_honey_for_bots">
  <%= label_tag :sweet_honey, "This is a honeypot, if you see this you're CSS is turned off or you're a bot. If you're not a bot don't fill it in." %>
  <%= text_field_tag :sweet_honey %>
</div>

Then go to your model and make your field accessible; attr_accessible :sweet_honey

One last quick step is to instruct your form what to do on save. You can have it simply fail with no error but that isn't accessible plus if anyone does fill it in, you might want to give a fun little message for them. I have my form rendering a partial because of the ajax-iness, plus I don't want the form to disappear just in case it's not a bot.

if params[:sweet_honey].present?
    format.html { render :partial => "emails/email_bot", :layout => false }
elsif @email.save
    ...
else
    ...
end

This is super simple implementation of a honeypot. I figured why make it more complicated when I just want to prevent send?

Lots of Love for ActiveAdmin

I have been so heavily immersed in work projects that I haven't had the time to write posts about rails - or do much of anything else.

Recently, I have been using the ActiveAdmin gem for the websites I've been building with rails. We are rebuilding our company website with rails and an ActiveAdmin backend. ActiveAdmin is awesome, the documentation could use a little love, but other than that I have no complaints about the system. I do believe everyone should build a rails administration system from scratch at least once to ensure understanding of how authentication works.

I'm going to go over some of the basics of getting up and running with ActiveAdmin and then in later posts will go into more detailed instructions on more complicated things you may want the admin to do like model relationships and integration with paperclip.

Installation

To get started add activeadmin and meta_search to your Gemfile. Bundle install and begin development! Activate the default admin user model by generating the resource: rails generate active_admin:resource AdminUser. The default login information is admin@example.com/password.

Beginning Development

First, the admin user model must be configured. An important thing to note on installation is that all the fields for the user are visible including encrypted_password, reset_password_token, etc and if you try to update/add a user before changing the available fields you will get a "mass assignment" error. Find the admin_users.rb in app > admin and add the following:

ActiveAdmin.register AdminUser do
  index do
    column :id
    column :email
    column :full_name do |field|
      "#{field.first_name} #{field.last_name}"
    end
    column :last_sign_in_at
    default_actions
  end

  show do
    attributes_table do
      row :id
      row :full_name do |field|
        "#{field.first_name} #{field.last_name}"
      end
      row :email
      row :last_sign_in_at
      row :sign_in_count
    end
  end

  form do |f|
    f.inputs "Edit User" do
      f.input :first_name
      f.input :last_name
      f.input :email
      f.input :password
      f.input :password_confirmation
    end
    f.buttons
  end

  filter :id
  filter :email
end

You'll notice I've added extra fields to the db, namely a first_name and last_name to create full_name. This file changes the main views in the administration interface — the index view (table of users), the show view (each user's settings), and the form (updating/adding users to the admin panel).

Be sure to update your model to include validations, messages and relationships.

Adding new models is as simple as generating a model and a resource. If you want to create a model that isn't updated through the ActiveAdmin interface, create a has_many join table model (ex, categorizations), but leave out the resource generation.

And that's all you need to get started, very simple gem to use. Although I could get a lot more in-depth about the features of ActiveAdmin I'm going to pause here. I encourage you to play around with it, the ease of use makes development even more fun. It's great to not have to worry about designing your admin interface for fast development.

My First Week with a Sit-Stand Desk

Although this pos is not related to Rails I thought it as valid becasue it's about the culture of technology companies and keeping that culture from being stale.

And sitting was getting stale. In fact, sitting had been stale for me for quite awhile because for a year and a half I have had on and off excurciating back pain that leads to migraine style headaches ad massive amounts of crankiness, not to mention the productivity you lose when all you can think about is the amount of pain you're in.

So this week I started with an ergotron sit-stand style desk. I would post a picture but I have yet to install paperclip on my blog for adding posts (I really should get to that).

The nice thing about this style desk is it can move up and down to be at the perfect height for your hands or so if you're tired of standing you can sit easily without needing to purchase a higher chair.

The company has many different styles from dual monitor to monitor and laptop, something for everyone. It attaches to an existing desk by a clamp which worked really well for my office because we have built in work stations that came with the office. It didn't require any decontruction of the stations.

I was surprised to find that I could stand almost all day. Of course I get fidgetty, but I was like that when I was sitting too. I don't know if I can say yet that I think better, but I am definitely less tired and in less pain. Good shoes are really important becasue my heels start to hurt if I'm not wearing supporive and comfortable ones. I encourage you to try it out if you can. I'll most iikely be purchasing a standing desk mat for computing barefoot so my heels don't hurt as much.

Categories: shoutouts tips

Errors: Ruby 1.9.3 - uninitialized constant Capistrano (NameError)

Today I learned that order does matter in your Gemfile.

I got the error uninitialized constant Capistrano (NameError) in the app I was developing when I tried to boot my local server. I had gem 'rvm-capistrano' listed before gem 'capistrano' - I guess when Rails tried to boot the app it read Capistrano from rvm-capistrano and assumed that Capistrano wasn't installed.

I intend to look deeper into this problem, but wanted to notfiy anyone who comes across the same issue.

I ended up solving this problem through Ruby Forum from someone with a very similar problem but slightly different solution.

Categories: learning-rails errors

Sorry for the Rough Travels

I am not entirely sure why yet but I have had a lot of trouble lately with this blog and it throwing 500 errors. I have been having a lot of troulble with MySQL - and at first I thought I fixed it and belive I made it worse. I have switched some stuff back and will hopefully soon figure out what the problem is and will be able to write a proper post about my troubles.

Airbrake a really nice app for this sort of thing because I don't need to read the logs to find out my site is trying to kill itself.

This is what is happening:

For awhile I was getting the following error:

ActiveRecord::StatementInvalid: Mysql::Error: MySQL server has gone away: SELECT `posts`.* FROM `posts` ORDER BY created_at DESC LIMIT 10 OFFSET 0

I added reconnect:true to the database.yml because I figured that would fix it.

What happened instead is really weird and I can't figure out why the above change would cause this. The app started throwing a new error, more often. The error is sometimes on posts and sometimes on categories and differs depending on the page but generally looks like this:

ActiveRecord::StatementInvalid: Mysql::Error: : SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = ? LIMIT 1

What is weird is that's it's not getting the ID, but the page URL knows the ID, for example, when I click the category name with the ID 3, the slug is '/categories/3', but still throws the error on that page the mysql query is not getting the ID.

Maybe the answer is simple, but googling for the error doesn't result in much useful information. For now I've switched it back to the verison without the "reconnect:true" to see if the erros switch back again.

If you have any idea why this would be happening and would be interested in helping me out I'd really appreciate it. Find me on Github or Twitter.

Categories: learning-rails updates

Installing Airbrake for Your Rails App

What is Airbrake

In addition to New Relic I have also added Airbrake to my blog. Again, Airbrake is very simple to add add to any Rails App.

The Airbrake App tells you if any of your projects throw and error, and also notifies you which of your app environments did so. You have the option of the error notifying you via email, only receive emails for the production environment or to participate in Airbrake's beta program.

It also has Lighthouse & Github integration as well as tracking your deployments which is nice and convenient.

Installation and Use

Adding the Airbrake app is easy and I'll even go over an error and solution that occurred for me. First create an airbrake account and create your first project. When you create the project directions for adding Airbrake to your app will be visible.

Add airbrake to your Gemfile. I found this did not play nicely when I put the app in only my production environment.

gem 'airbrake'

Run bundle install. Then run script/rails generate airbrake --api-key YOUR_API_KEY_HERE. You can get your api key from that first screen when you create your first project. If this runs successfully you will see the airbrake test run in your terminal, followed by your configuration options which contain your api key, etc.

      append  config/deploy.rb
      create  config/initializers/airbrake.rb
         run  rake airbrake:test --trace from "."
** Invoke airbrake:test (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute airbrake:test
Configuration:

Now if you're using Capistrano you're probably wondering if there is anything special you need to do for your deploy. The good news is that Airbrake will add require 'airbrake/capistrano' to your deploy.rb automatically. The bad news is that my capistrano script broke after the addition of airbrake. Previous apps we have Airbrake installed on run fine so I'm not sure if it's certain versions of gems, ruby or rails that throws the errors.

If you see an error that says `require': no such file to load -- rvm/capistrano (LoadError)" then you probably have the same problem I have. After a little bit of research I found others had the same problem and reported that removing require './config/boot' from the deploy.rb fixed the problem. Once I removed this it ran fine and airbrake noted my deploy. The problem I found is a know issue reported on github as Issue #26 - if you'd like to follow the progress of this error you can read up on it here.

Installing New Relic for Your Rails App

What is New Relic?

New Relic is a performance management system that our company just started using to monitor some of our larger apps. Since this app occasionally drops mysql connection (I'm thinking it's related to Unicorn) we're using it as a test case.

By using New Relic you can get real-time browser performance, app performance, database performance, email notifications. And on top of being a great resource it looks awesome. Some really nice design there.

Installation and Use

Installation for Rails Apps is easy. Add the gem to your Gemfile inside your production group.

gem 'newrelic_rpm'

When you're done with that add newrelic.yml Inside your config/ folder inside your app. You can get the default settings from the github project.

You'll need a license key and to change your group's based on your configurations if you don't want the default options.

Once deployed New Relic automatically recognizes your Rails App and begins monitoring it. It monitors who is visiting your site and from what country as well as all the processes it is running. Definitely worth checking out.