Eileen speaking at Rails World The Myth of the Modular Monolith at Rails World. Photo by Aaron Patterson.

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.

Nifty Rails Methods: link_to_if, link_to_unless

I have for some time been wanting to make a "definitive list of awesome rails methods". There are so many great built in methods that I didn't realize existed when I was trying to build something from scratch. Sometimes it's annoying to find out that thing you're trying to build already exists - but if you haven't put 500 hours into it, it's usually a relief.

So today the featured definitve list of awesome rails methods are link_to_if and link_to_unless.

The nice thing about this method is it's great for changing links based on if a user is logged in, if the page is current, etc. Instead of writing an if else statement you can DRY it up by using link_to_if or link_to_unless. I found it fun to play around with and very useful as well. I personally used it for a complicated if else to mark a category for a prodcut as current. There is also an link_to_unless_current which I didn't end up using because it wouldn't mark both the current category and parent category as active, link_to_if worked much better for that.

Below is an example from the Rails API

<%= 
  link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) do
     link_to(@current_user.login, { :controller => "accounts", :action => "show", :id => @current_user })
  end
%>

More about these methods can be found on the Rails API.

There's More to User Experience Than Ease of Use: Lessons in Not Scaring Your Customers

This post is not really going to be Rails related. But everything in a Rails blog doesn't need to be about Rails, or Ruby, or coding at all.

I feel like Rails is an experience, in not being frustrated with everything and it's easier to map out an application. The things that get in the way of building something awesome, the time consuming, awful things like join queries and pluralization are done for you. You can focus on your application and it's beauty and structure.

Well, user experience is also an experience and I hate that it's so often that a website has me banging my head against a wall. Recently, I logged on the Sallie Mae website to check something with my student loan. Being that I have it set for auto-debit and that I was logging in on a weekend I was met with a front page telling me I was delinquent on my loan.

Now people who know me will know my reaction without telling you. I literally flipped a shit. Thinking my bank account information was lost or some other awful scenario (was my bank account hacked and emptied?? no...it wasn't phew) I searched through my account for an answer when the answer occurred to me.

Sallie Mae does not have a failsafe in place so that when you have auto-debit activated and the date of debit falls on the weekend it doesn't "figure it out" it instead tells you you didn't pay and that you better do it now.

Awesome. Please when building an application make sure you put in if else statements that check for things like weekends, and auto-debit. It will make your customers happy. No one wants a mini heart attack on Sunday evening, to log in the next day and see all is well.

User experience is more than making a site easy to use, and beautiful (both which Sallie Mae fail at). It's also about not scaring the crap out of your clients and consumers — or accepting 76 early acceptance students accidentally (I'm looking at you Vassar). When desiging a web application consider all the horrible things that can go wrong for the user, not just you the developer and put failsafes in place to prevent those things. You will have happier clients that will keep coming back again and again.

Frustration is never good for business.

Categories: tips user-experience

Adding Additional Functionality to "Forgot your password?"

Recently I needed to add "forgot your password?" to a Rails app built by my company. I had never done this before so I watched the Remember Me & Reset Password Railscasts screencast. It was infinitely helpful, but I added a few things that were not in the video that I would like to share here. I followed the screencast for the most part: Adding a password_resets controller, in addition to following the auth_token directions. One thing I added was an intermittent page, instructing the user to check their email. I used the index.html.hamllayout for this. In addition I did not like it that users who hadn't requested a new password could access these pages, so I created a few redirects to prevent that. My index and new action show this redirect protection.

If a user attemps to go to the password_resets while already logged in they will be redirected to their profile, if they try to get there without being logged in they will be redirected to the login page, same with the new action.

# index and new action in my password resets controller
def index
  if current_user
    redirect_to account_url
  else
    redirect_to '/login'
  end
end

def new
  if current_user
    redirect_to account_url
  end
end

I added the functionality to check whether the user's email was in the database and to return an error if it was invalid.

On the create action I have the page rendering the index instead of redirecting to maintain access to the email address so the view can display "An email has been sent to "insert email address". You must click the link in the email to reset your password."

# create action for generate password token for forgot password
def create
  user = User.find_by_email(params[:email])
  if user
      user.generate_password_reset if user
      render :index
  else
    flash.now.alert = "No such email address was found. Please try again."
    render :action => 'new'
  end
end  

Lastly, I wanted to make it more secure than the token expiring in 2 hours, so I added code that make the token expire if the user successfully changed their password. Once the user successfully changes their password reset_pass_token will be erased from the database and will be redirected to their account profile, so they can edit other settings if they like otherwise, they recieve errors. If the new password save isn't successful within 2 hours the token will also expire.

def edit
  @user = User.find_by_reset_pass_token(params[:id])

  if @user.nil?
    redirect_to '/login', :alert => 'Password reset does not exist.'
  elsif @user.reset_pass_expiration < 2.hours.ago
    redirect_to '/login ', :alert => "Password reset has expired."
  end
end

def update
  @user = User.find_by_reset_pass_token!(params[:id])
  if @user.update_attributes(params[:user])
    @user.reset_pass_token = nil
    @user.save!
    # if params are updated create session for user by matching token and pass
    if @user.valid?
      session[:user_id] = @user.id
      redirect_to account_url, :notice => "Your password has been reset!"
    else
      render 'update'
    end
  else
    flash.now[:error] = @user.errors.full_messages
    render :action => "edit"
  end
end

The setup for "Forgot your password?" was rather easy and I learned a lot from implementing the functionality.

Categories: learning-rails

The Footnotes Plugin for Textmate

Around the beginning of the year I decided to watch every Railscast tutorial. I know what you're thinking — that this was a "New Year's Resolution". Well that's simply not true. It just appears to be one. I resolved to do that way before the New Year, it just so happened that on January 3rd is when I had time to start.

Well some people have said, why watch every one? They are old and from 2007 and some aren't relevant anymore. That may be true, but at EMN we have some legacy Rails sites that I didn't build but might have to one day fix, and it helps to know what has changed from Rails 2 to Rails 3, etc.

I've also learned some really great things and tips. One in particular is the footnote plugin for textmate which links the error messages in Rails to where they appear in your code. In your footer it also describes the SQl calls & queries, and analyzes the speed, shows the CSS and HTML and everything you might want to inspect for that code. The video that describes it is "The Stack Trace" and although the method for installing the plugin shown in the video no longer works you can download it from github and follow the installation instructions there. It needs to be installed for each app and added to your .gitignore because this plugin should only be used in development mode.

Happy coding!

Categories: shoutouts tips