In order to learn Ruby on Rails I’ve been working through the 3rd edition of the Ruby on Rails tutorial. Upon reaching the second part of Chapter 9, Account Activation and Password Reset, I decided to implement the feature on my own to test and improve my understanding of Rails.

  1. User clicks ‘Forgot password’ link on Sign in page <%= link_to 'Forgot password', new_password_reset_path %>
  2. GET request sent to new_password_reset_path ⟶ password_resets/new ⟶ password_resets#new
  3. User enters email address in text field and clicks button
  4. POST request sent to password_resets_path ⟶ password_resets/ ⟶ password_resets#create
  5. User gets email with reset token and email address in link
  6. User clicks link in email
  7. GET request sent to edit_password_reset_url ⟶ password_resets/:id/edit ⟶ password_resets#edit
  8. User enters new password and confirmation
  9. PATCH request sent to password_reset_path ⟶ password_resets/:id ⟶ password_resets#update
  10. If password and confirmation do not match user is redirected back to the root_url. This is a limitation of the if statement in password_resets#update

Differences

session[:email] vs. hidden_field_tag :email, @user.email

  • Allows for repeated use of params[:email]

Refactor:

@user = User.find_by(:email, params[:email])
@user && @user.authenticated?(:reset, params[:reset_token])

into a private get_user method and use a before_action callback for edit and update actions in the password_resets controller.

update_attribute vs.user_params and update_attributes

  • Should this method always be used?
  • Do we use it when a user updates their info?
  • When is it not used? Only during token creation and subsequent digest updates to the db?

Notifies submitter if an email address isn’t on file

If an invalid submission is submitted then the submitter is notified that the address isn’t on file. This would actually allow someone to determine if a particular user has an account with the service instead of silently doing nothing. As a result I’ve modified the create action in PasswordResetsController to always display the flash[:info] message of Password reset email sent. but only send the email and set a token if the user exists in the database already.

Doesn’t cover edge case of when logged in and trying to change password

PasswordResetsController
...
def create
  if logged_in?
    redirect_to edit_user_path(current_user)
  else
    render 'new'
  end
end
...

Doesn’t remove reset_digest and reset_sent_at after successful password reset

Add

@user.update_columns(reset_digest: nil,reset_sent_at: nil)

to update action in PasswordResetsController after a successful update.


When using test-kitchen for testing Chef cookbooks you may run into the following error:
I cannot read /tmp/kitchen/client.pem, which you told me to use to sign requests!
This results from using the chef-solo provisioner and having a search() function call in your recipe. test-kitchen is trying to reach the Chef server but it can’t since it doesn’t exist. Switch over to using chef-zero and put node JSON data in test/integration/nodes that can be searched against.

However, if your recipe is searching for a node based on a recipe, test-kitchen doesn’t properly return the nodes so you may need to detect if you’re running in a different environment within your cookbook and react accordingly.


The opscode application cookbook doesn’t like working with branches and this has been going on for a while now:

http://lists.opscode.com/sympa/arc/chef/2013-07/msg00334.html

https://github.com/opscode/chef/issues/1563

Only solution still seems to be shallow_clone false


Chef notifications can use the notifies attribute to notify other resources about actions they may need to take either :immediately or at the end of the chef-client run by using the :delayed option. This seems to allow one to notify an existing resource on the current node but what about notifying another node that something needs to happen? Having another node call chef-client on an existing node would require that a user exists on the calling node that has SSH access to the called node.


I have migrated back to Linode due to price vs. performance analysis of Rackspace’s legacy cloud servers. xxx


Working through the Ruby on Rails Tutorial for Rails 4.0 and pushing to heroku after adding the bootstrap css and assets the css files were coming up blank.

Changing config.assets.compile to true in config/environments/production.rb seemed to fix the issue but I didn’t want to leave it configured this way.

Reverting this change and pushing to Heroku brought the behavior back. Running heroku run rake assets:precompile seems to fix the issue.

UPDATE: Seems this is only a temporary fix. According to this post it’s an issue with Heroku’s support of Rails 4.


If vim-rubytest.vim is using the system ruby when you want it to use the current rvm zsh may be at fault. On OS X rename /etc/zshenv to /etc/zshrc.


The Ruby on Rails Tutorial now has a beta version addressing the necessary changes in Rails 4. One of these changes is the use of Capybara 2.1.0.beta1 which now uses feature specs instead of request specs. The current version of the book still uses request specs so I’m going to detail the changes I made to use the new feature specs in Capybara.

The current version of Chapter 3 lists the following for spec/requests/static_pages_spec.rb:

require 'spec_helper'

    describe "Static pages" do

      describe "Home page" do

        it "should have the content 'Sample App'" do
          visit '/static_pages/home'
          expect(page).to have_content('Sample App')
        end

        it "should have the title 'Home'" do
          visit '/static_pages/home'
          expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home")
        end
      end

      describe "Help page" do

        it "should have the content 'Help'" do
          visit '/static_pages/help'
          expect(page).to have_content('Help')
        end

        it "should have the title 'Help'" do
          visit '/static_pages/help'
          expect(page).to have_title("Ruby on Rails Tutorial Sample App | Help")
        end
      end

      describe "About page" do

        it "should have the content 'About Us'" do
          visit '/static_pages/about'
          expect(page).to have_content('About Us')
        end

        it "should have the title 'About Us'" do
          visit '/static_pages/about'
          expect(page).to have_title("Ruby on Rails Tutorial Sample App | About Us")
        end
      end
    end

Once we complete exercise #2 at the end of the chapter we can update the spec to use the new syntax of feature specs like so:

require 'spec_helper'

    feature "static pages" do

      given(:base_title) { "Ruby on Rails Tutorial Sample App" }

      describe "Home page" do

        scenario "should have the content 'Sample App'" do
          visit '/static_pages/home'
          expect(page).to have_content('Sample App')
        end

        scenario "should have the right title" do
          visit '/static_pages/home'
          expect(page).to have_title("#{base_title}")
        end

      end

      describe "Help page" do

        scenario "should have the content 'Help'" do
          visit '/static_pages/help'
          expect(page).to have_content("Help")
        end

        scenario "should have the right title" do
          visit '/static_pages/help'
          expect(page).to have_title("#{base_title} | Help")
        end

      end

      describe "About page" do

        scenario "should have the content 'About'" do
          visit '/static_pages/about'
          expect(page).to have_content("About")
        end

        scenario "should have the right title" do
          visit '/static_pages/about'
          expect(page).to have_title("#{base_title} | About")
        end

      end

      describe "Contact page" do

        scenario "should have the content 'Contact'" do
          visit '/static_pages/contact'
          expect(page).to have_content("Contact")
        end

        scenario "should have the right title" do
          visit '/static_pages/contact'
          expect(page).to have_title("#{base_title} | Contact")
        end

      end
    end

Unfortunately this still uses the describe keyword from the request specs DSL due to not wanting to repeat the use of given for each scenario.


When using RubyTest in Sublime Text 2 to run my tests I initially received an error:

/bin/sh: rspec: command not found

Further research suggested that due to the use of rvm I needed to cd into the rails project directory and then run

subl .

Once I did that I no longer received an error but I also received no output at all. Using

ctrl + `

I was able to determine a different error regarding UnicodeDecodeError. Turns out it is most likely linked to my used of bash-powerline and a fix was mentioned to the Sublime Core team. In the interim changing the code on line 45 of /Users/metafour/Library/Application Support/Sublime Text 2/Packages/Default/exec.py from

proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())

to

proc_env[k] = os.path.expandvars(v.decode(sys.getfilesystemencoding())).encode(sys.getfilesystemencoding())

seems to fix the problem.


Looking towards the future I’ve decided to learn Ruby on Rails. I started out by doing the Rails for Zombies course and consequently the Try Ruby course. While they both incorporate an interesting set of exercises they don’t really develop any understanding of the material. I then moved onto the Ruby on Rails Tutorial. This pushed me to look back into using vagrant for virtual environments as well as expanding the use of tools such as vim, tmux, bash scripting, python, and the list goes on.

vagrant, iterm2, vim, and tmux

I decided to look into vagrant for running some linux VM’s so that I could leave my mac environment pristine. This led to using tmux and vim on the command line as a development environment. As much as I like vim this was taking a step back to when I was using linux exclusively. Setting up panes in tmux, configuring this and that, and then not being comfortable with the results. Therefore, I decided to switch to the tutorial’s recommended setup of Sublime Text 2.

Sublime Text 2 and Transmit

In order to gain access to the files in the development environment on the VM I decided to use Tranmit’s disk feature. Mounting the home directory of the vagrant user and then loading the rails folder into sublime. I installed the RubyTests package and then tried to run a test only to have it fail due to not actually being in the ruby environment on the VM.

RVM and pow.cx

I’m now going to move to using RVM and pow.cx on the local Mac installation to see how it goes.


⇧⌘. – Show hidden files and folders in Open Dialog


Since Coda 2 is on sale I would like to try it out in order to determine if it is a good fit for my personal site workflow. I need to start out by testing git functionality. Seems git support is not working as well as I had hoped and there is no documentation available on it in the help files or on panic.com.

UPDATE: I purchased Coda 2 the first day it was launched. It has now become my goto app for updating the website. I figured out he git configuration and since updates are handled via post commit hooks I can easily type up or edit a post and have Coda 2 commit and update the site with a couple of clicks. If I don’t feel like using the command line interface to update the site I no longer have to. Definitely worth the purchase.


The keys to success according to John Gruber:

  1. A fussy way to make coffee
  2. A clicky keyboard
  3. A Sodastream


⌘0 – Show/hide Navigator
⌥⌘0 – Show/hide Utilities

⌘↩ – Show Standard Editor
⌥⌘↩ – Show Assistant Editor
⌥⌘. – Move focus to next area
⌥⌘> – Move focus to previous area
^6 – Methods drop down

⇧⌘C – Show debug console
⇧⌘Y – Hide debug console
⇧⌘O – Open Quickly
⌘B – Build
⌘R – Build and Run
⌥⌘C – Commit

⌥-rightclick – show information popup for method or class
⌥-doubleclick – show documentation for method or class


Safari Insert Cursor Into Web Search Box

⌥⌘F


OS X Lion Disable New Window Animation

defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO

OS X Lion Restore “Cmd”-D Behavior on Save Sheets

defaults write NSGlobalDomain NSSavePanelStandardDesktopShortcutOnly -bool YES


#!/usr/bin/python

n = raw_input('n = ')

n = int(n)

if n % 3 == 1:
	print "f(n) = %d" % (3**(n//3-1) * 2**2)
elif n % 3 == 2:
	print "f(n) = %d" % (3**(n//3) * 2)
else:
	print "f(n) = %d" % (3**(n//3))


BBEdit

In order to code quickly I’m used to the ability to hit ⌘↩ to move the cursor to the end of the current line and then create a new line. Also for files indentified as python source code ⇧⌘↩ inserts a : at the end of the current line and creates a new line.

First, I tried to use Clippings. Clippings do not allow you to manipulate cursor movement relative to the current line.

Next, I tried using DefaultKeyBindings.dict to achieve this.

DefaultKeyBindings.dict

{
  "@\U000D" = ( moveToEndOfLine:, insertNewline: );
  "~\U000D" = ( moveToEndOfLine:, insertNewline: );
}

Unfortunately it seems that BBEdit doesn’t use the Cocoa Text Object and therefore doesn’t use these new key mappings.

I broke down and emailed support@barebones.com about my predicament and asking for a pointer in the right direction. The reply I received point me to AppleScript.

AppleScript

I was hoping this would be as simple as the DefaultKeyBindings.dict syntax in that I could just say move the cursor to the end of the current line and then insert a new line. Not so simple. Here’s the code to actually get this to work using BBEdit’s AppleScript Dictionary:

tell application "BBEdit" to tell front window
  set lineNum to startLine of selection
  set len to length of line lineNum
  if len > 0 then
    select insertion point after (character (len) of line lineNum)
  end if
  set selection to return
  select insertion point after selection
end tell

If I want to insert a colon at the end of the line then line 7 above looks like:

set selection to ":" & return

This can also be achieved using the System Events application using the following code:

tell application "BBEdit" to tell front window
  activate
  tell application "System Events" to keystroke (key code 124 using command down)
  tell application "System Events" to keystroke ":"
  tell application "System Events" to keystroke return
end tell

Now that I have scripts that can replicate the behavior I need I can create Application Keyboard Shortcuts that trigger the scripts and I’m all set.

Issues

So apparently there are multiple ways of setting a keyboard shortcut for BBEdit. The standard method involves using the System’s Keyboard Preference Pane to map a menu item to a keyboard combo. This method does not allow one to use the Return key in the combination. The next method is from within BBEdit’s preferences itself. Again this method does not allow the use of the Return key in the combination. Finally there is a palette for some of the menu items that allows one to assign a keyboard shortcut to menu items. This method allows the use of the Return key in the keyboard combination.