Fancy Forgot Password with jQuery/ui and Rails

By now, you have to know how fascinated I am by jQuery, and how much I love using it with Rails to make things simple, yet slick. Last week I did some wireframes for a client, and one of them was the “Forgot Password” feature… which I displayed in a modal dialog in the w/f. It seems to me that popups make sense for these kinds of things, rather than fully redirecting to another page, then upon successful password email, redirecting to even another page. So here was my fast, easy solution using jQuery (+jQuery-UI) and Rails.

First, make it work without Javascript and write your unit tests so they pass accordingly. Accessibility is at stake here people and we want to make sure anyone can retrieve their password at any time. My approach, just so you can follow the logic easily, is the following:

  1. User clicks Forgot Password link
  2. User enters email address
    • Invalid?
      1. Throw an error
    • Valid?
      1. Set new password
      2. Send email containing new password
      3. Alert with success message

So we create our controller method, our view, our notifier, and, if you like (I did), a method on our user model that does the setting and delivering of new password.

Code after the jump!

Continue reading

Posted in Development, jQuery, Ruby on Rails | 5 Comments

Install Ruby, Rails and Subversion … in under 15 minutes.

Quick and Dirty Install

Assumes you are logged in as root. Use sudo where necessary (like any make or gem installs). Skip the steps that you already have (i.e. Ruby/RubyGems installation)

Install dependencies:

yum -y install zlib openssl-devel readline-devel gcc-c++

Install Ruby and RubyGems (if the REE installer fails for lack of finding an interpreter):

wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
tar -zxvf ruby-1.8.7-p72.tar.gz
cd ruby-1.8.7-p72
./configure
make && make install
wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
tar -zxvf rubygems-1.3.1.tgz
cd rubygems-1.3.1
ruby setup.rb

Install Ruby Enterprise (if you are on a 64-bit distro, you may have duplicate i386 AND x86_64 versions of libstdc++ and you will get an error… either uninstall the i386 version, or add –no-tcmalloc option to installer command):

wget http://rubyforge.org/frs/download.php/51100/ruby-enterprise-1.8.6-20090201.tar.gz
tar -zxvf ruby-enterprise-1.8.6-20090201.tar.gz
./ruby-enterprise-1.8.6-20090201/installer
/opt/ruby-enterprise-1.8.6-20090201/bin/passenger-install-apache2-module

Add the following directory to your path (you could use symlinks too)

/opt/ruby-enterprise-1.8.6-20090201/bin

Add the following to Apache config:

LoadModule passenger_module /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.x/gems/passenger-2.0.6/ext/apache2/mod_passenger.so
PassengerRoot /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.x/gems/passenger-2.0.6
PassengerRuby /opt/ruby-enterprise-1.8.6-20090201/bin/ruby

Install any gems you want or that are required that *did not* get installed as a result of the REE installer..

gem install passenger rake rails fastthread rack sqlite3-ruby postgres
gem install mysql -- --with-mysql-config='/usr/bin/mysql_config'

Install Subversion:

yum install subversion

Create repository:

mkdir /usr/local/svn/repos/
svnadmin create /usr/local/svn/repos/project
chown -R apache:apache /usr/local/svn/repos/project

Add the following lines to subversion.conf (or whatever apache config file you choose to use):

<Location /svn/repos>
DAV svn
SVNParentPath /usr/local/svn/repos
</Location>

Create a password file:

htpasswd -cm /etc/svn-auth-file username

Add more usernames/passwords:

htpasswd -m /etc/svn-auth-file username

Modify your subversion.conf to use whatever security method you deem necessary

Create your rails app:

rails rails_app

Import your rails app:

svn import -m "Initial import" rails_app file:///usr/local/svn/repos/project

Add virtual host for rails app (this will entirely depend on your server/application setup, but mainly concern yourself with the fact that your DocumentRoot and Directory directives should have /public at the end):

<VirtualHost *:80>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /path/to/rails_app/public
ServerName yourdomain.com
ErrorLog logs/yourdomain.com-error_log
CustomLog logs/yourdomain.com-access_log common
</VirtualHost>

Done. Time to go caffeinate.

Full install approach after the break.
Continue reading

Posted in Development, Ruby on Rails, Subversion | Leave a comment

Quick, Clean & Easy Form Popups (Dialogs) w/ jQuery … Eeeee!

The following itty-bitty snippet loads a page from my site (the new connection type page in this case), grabs the form out of it, injects it into a div which gets injected into the body of the page, then calls dialog on it. :) ComPLETEly unobtrusive, and I don’t have to mess with any of my controllers or views to make it work. :) Ahhh the simplicity.


<a href="/connection_types/new/" class="popup">Add Connection Type</a>

$('a.popup').click(function() {
	$('<div />').appendTo('body').load($(this).attr('href') + ' form').dialog({
		title: $(this).text()
	});
	return false;
});

Read the docs for more info…

Posted in AJAX, jQuery | 5 Comments

Association IDs with Ease

Holy crap, that is a corny title. Oh, but it does have a point! I found this out the other day, and who knows how long it’s been in Rails ( didn’t check the old docs ) , but you can actually assign collection ids to an associated object! Ok that’s confusing, just here’s the example already:

I was working on a trip booking site in Rails, and I needed the ability to assign optional “excursions” to “passengers”. So of course UI-wise, I’m using checkboxes… but backend-wise I’m thinking ‘crap, I don’t want to loop through each of the selected ones and assign them one at a time’. Literally, that’s what I was thinking. So I did some snooping of the Rails docs in the Association::ClassMethods area… and found the following VERY useful info. :)

My example, uses the checkboxes, so in my view I have the following (note the empty string as the last param on the check_box, so that the default/unchecked value is NOT 0 (zero) .. that is unless you want to do more logic in your controller to check for 0 values to throw out).. anyway, the code:


<% @trip.excursions.each do |excursion| %>
  <%= check_box :trip_excursion, :excursion_id, { :id => "excursion_#{excursion.id}", :name => 'excursions[]' }, excursion.id, "" %>
  <%= label 'trip_excursion', 'excursion_id', "#{excursion.name} #{excursion.days_offered}", :for => "excursion_#{excursion.id}" %>
<% end %>

Then in my passengers controller (both create and update methods), I simply have:


@passenger = @trip.passengers.create params[:passenger]
@passenger.excursion_ids = params[:excursions]

One of my favorite things is, you can say collection_ids = *anything .. it can be null, an empty array, an empty string, a not-empty array, a single integer, and so on and so forth. This was actually very useful for doing the update (moreso than the create), since doing the update would have otherwise required checking for already selected excursions and comparing the values of the params, deleting those that were no longer “checked”. This takes care of that by just setting the IDs explicitly, which will automatically remove the associations that are no longer in the new value-set. :) Happy coding…

Posted in Development, Ruby on Rails | Leave a comment

Ruby on Rails SEOness

So since SEO law says that you can’t reuse keywords over and over on pages without being banned, I’ve come up with this (not entirely unique or clever) solution. Basically, you’re going to set up an array with as many keywords as you can possibly think of to define your site. (Literally… as many as you want, hundreds.. thousands.. doesn’t matter.) Then we’re going to shuffle it up and chop it down to only 20 of your faves. :) You could also write a method that combines these steps if you really have thousands of keywords, I only had 40 so this was fast enough, but for thousands… there is definitely something more efficient.

Define a new method for an array to do your shuffling:


class Array
  def shuffle!
    each_index do |i|
      j = Kernel.rand(length-i) + i
      self[j], self[i] = self[i], self[j]
    end
  end

  def shuffle
    dup.shuffle!
  end
end

Then in your application_helper.rb (or wherever you want, just probably easiest in app helper), do something like:


@@site_keywords = ["blah", "blip", "bleee", "bleh", "blop", "blow", "blum", "blay", "blue"]

def site_keywords(num=20)
  @@site_keywords.shuffle[1..num].join(", ")
end

…you’ll want to use more than 8 in your array, I’m sure…

Lastly, in your application.html.erb (or application.rhtml if you’re rollin’ old school style), put this inside your head tags:

<meta name="keywords" content="<%= site_keywords %>" />

OR to choose how many keywords show up …

<meta name="keywords" content="<%= site_keywords(40) %>" />

That’s it! Tough stuff, I know…

Posted in Development, Ruby on Rails | Leave a comment