Posts tagged rails

Good, Simple Design

I’ve heard this re-framed again and again by many different programmers from @wycats at Ruby conf to @dhh in his parlay letter:

I consider this [the ease of getting started], like maintainability, to be a side effect of good, simple design.

I think this is a great way of looking at the “beginner” problem, but it doesn’t give much guidance. What exactly is good design for advanced developers? Why is it also good for beginners? Who counts as a beginner? Is a .NET dev with 5 years of industry experience learning rails lumped into the same category as a someone who had never previously viewed-source on a webpage?

In the Beginning

Let’s take it back a bit, to the era before one click purchases, and github signup buttons. The realm was ruled by the textbox and it’s mighty accomplices radio buttons, text areas, and submit buttons. Signing up for a new web app was a lesson in finger cramps. Eventually some people were clever enough to figure out that fewer fields meant fewer interactions, and less fatigue. This of course lead to fewer people dropping off and higher sign-up numbers. Good for the business, who now has more users. Good for you, who now has to type. In the end all they needed was a password and an email, the rest was just details.

What do web forms have to do with advanced programming? Everything. It doesn’t matter if you were browsing the BBS on a 28.8k or you just got your first taste of the Internet over AOL, you had to go through the same interaction. Experience was irrelevant. There was no “click here if you understand the internet” signup option. So when the pain of signing up for many many services by the elite trickled down to help the newbs signing up for their first service: every won.

Anectdotes aside, this is how coding for interaction should be. Build for the pros, don’t forget the nos. What can we as developers take away from the signup form? Treat each user interaction as a barrier to entry and productivity, slash cut and simplify until you can’t be simpler, and treat the interface as a tool to reduce activation energy.

PROTIP: Look for heavy process and cut it down to size

Sometimes the simplicity can come from an internal structure, let’s take a look at how re-thinking how routes are groked led us to a more productive programmer and eventually a smarter “beginner”.

Simplicity in Action: Sextant

A Sextant is an ancient tool for finding your route via the stars. My program Sextant is a tool for finding your rails routes via your browser. I started the project to save me from the pain of rake routes to slash my waiting time (counted in agonies per command, of course) from 20 to 0.

What started as a simple tool for saving time has since ballooned into a new way to visualize and think about a core part of our Rails coding experience, with over 39 thousand downloads. The key to it’s success was identifying that extra step that wasn’t needed, the boot time of the rails app. Now that sextant is shipping with Rails 4 we can start the process over again. What else isn’t needed, or what is missing?

The Evolution of an Interface

Once we got the routes into the browser we’ve now got a powerful set of interaction tools to work with, namely html and javascript. I was able to clean up the visuals of the routes a bit, but it always bothers me when the computer knows the answer to something and yet makes me do the work. Named routes which are a commonly used element in the views, are listed not as they are intended to be used, but instead only have their prefixes in the output. So instead of new_users_path I’ll often type new_users into a view by accident when I’m tired or distracted. When I hit refresh the page I see my problem, I forgot to do my mental math and add the _path suffix. When you’re already tired, already frustrated, just trying to ship a feature these seemingly small hoops to jump through grow ever larger with each mistake made. Why not remove them entirely?

The solution is to add this info into the view by displaying the full named route helper:

I think this is great. But why, what makes this a good idea?

‘Don’t make me think’

Rails is famously convention over configuration. This saves you, the developer, countless hours debating where to put your files or and what to name your folders. While this eliminating these extra steps is a great thing, something can get lost in the translation:

The first thing this current class of students asked me is “Where can I find the document that describes all of the Rails conventions.” - @steveklabnik

As you’re removing steps, if you miss some, then you’re secretly adding a hidden step to Google for for awhile. This Google tax only comes to: the new, the uninformed, the tired, and the overworked programmer trying to ship at the last minute. It’s easy to forget once you know the missing step by heart. This is why being explicit with route helpers in Sextant makes an impact. We took the hidden step “add _path to the end of these” and made it explicit without losing any information (you can still see that _url is an option):

PROTIP: Mental math leads to errors, where can we be more specific?

While you’re refining and iterating and slashing steps, don’t forget to keep context front and center. If you’re looking for places where you might need better docs, or more accessible information. I recommend you keep a …

Cheat Sheet

I use Evernote to keep track of the text snippets and docs links I end up finding useful. Not only does it help to organize my thoughts while I’m having issues, I can search it later if I run into the same problem, and even better when I’m bored or looking for something to productively procrastinate with, these notes are great places to see if we could add more docs, take away steps, or remove some mental math.

Design for All

If I can make my interface so simple it only needs one step, maybe one day we can eliminate the need entirely. This is exactly how automation is born and thrives. While it’s obvious saving developer time is a good thing, why had no one done this before, and how can you build better software for all levels?

  • Keep a cheat sheet
  • Look for duplicate or un-needed steps
  • Look for long complicated processes
  • Look for missing docs or implied information

Get up and make a difference, work with more beginners, contribute to open source and help close the gaps.


Richard “@schneems” (pronounced like Schnapps) Schneeman writes Ruby code for @heroku and teaches Rails at the University of Texas.

Custom Wizard URLs in Rails with Wicked

I wrote this wizard controller library that people seem to really dig called Wicked. It works well to build after signup wizards and to incrementally build objects for the database but there is one thing it didn’t do very well until now: allow you to change the text in your wizard url’s quickly and easily.

If you’re new to Internationalization (I18n) it’s a process of making your website look native in more that one language. With the newly released Wicked you can translate your wizard urls or simply use it to change your custom urls in one language with no code changes. Check it out:

Internationalization of URLS (I18n)

If your site works in multiple languages, or if you just want more control over how your URL’s look you can now use I18n with wicked. To do so you need to replace this:

include Wicked::Wizard

With this:

include Wicked::Wizard::Translated

This will allow you to specify translation keys instead of literal step names. Let’s say you’ve got steps that look like this:

steps :first, :second

So the urls would be /after_signup/first and /after_signup/second. But you want them to show up differently for different locales. For example someone coming form a Spanish speaking locale should see /after_signup/uno and after_signup/dos.

To internationalize first you need to create your locales files under config/locales such as config/locales/es.yml for Spanish. You then need to add a first and second key under a wicked key like this:

es:
  hello: "hola mundo"
  wicked:
    first: "uno"
    second: "dos"

It would also be a good idea to create a english version under config/locales/en.yml or your english speaking friends will get errors. If your app already uses I18n you don’t need to do anything else, if not you will need to make sure that you set the I18n.locale on each request you could do this somewhere like a before filter in your application_controller.rb

before_filter :set_locale

private

def set_locale
  I18n.locale = params[:locale] if params[:locale].present?
end

def default_url_options(options = {})
  {locale: I18n.locale}
end

For a screencast on setting up and using I18n check out Railscasts. You can also read the free I18n Rails Guide.

Now when you visit your controller with the proper locale set your url’s should be more readable like /after_signup/uno and after_signup/dos.

Wicked expects your files to be named the same as your keys, so when a user visits after_signup/dos with the es locale it will render the second.html.erb file.

Important: When you do this the value of step as well as next_step and previous_step and all the values within steps will be translated to what locale you are using. To translate them to the “canonical” values that you’ve have in your controller you’ll need so use wizard_value method.

For example, if you had this in your controller, and you converted it to a use Wicked translations, so this will not work:

steps :confirm_password, :confirm_profile, :find_friends

def show
  case step
  when :find_friends
    @friends = current_user.find_friends
  end
  render_wizard
end

Instead you need to use wizard_value to get the “reverse translation” in your controller code like this:

steps :confirm_password, :confirm_profile, :find_friends

def show
  case wizard_value(step)
  when :find_friends
    @friends = current_user.find_friends
  end
  render_wizard
end

The important thing to remember is that step and the values in steps are always going to be in the same language if you’re using the Wicked translations. If you need any values to match the values set directly in your controller, or the names of your files (i.e. views/../confirm_password.html.erb, then you need to use wizard_value method.

Custom URL’s

Very similar to using I18n from above but instead of making new files for different languages, you can stick with one language. Make sure you are using the right module:

include Wicked::Wizard::Translated

Then you’ll need to specify translations in your language file. For me, the language I’m using is english so I can add translations to config/locales/en.yml

en:
  hello: "hello world"
  wicked:
    first: "verify_email"
    second: "if_you_are_popular_add_friends"

Now you can change the values in the URL’s to whatever you want without changing your controller or your files, just modify your en.yml. If you’re not using English you can set your default_locale to something other than en in your config/application.rb file.

config.i18n.default_locale = :de

Important: Don’t forget to use wizard_value() method to make sure you are using the right cannonical values of step, previous_step, next_step, etc. If you are comparing them to non wicked generate values.

Custom crafted wizard urls: just another way Wicked makes your app a little more saintly.


Richard @schneems (pronounced sorta like Schnapps), loves writing gems and works for Heroku. If you enjoy the wicked gem consider watching the repo or telling your friends.

Reddit on Rails part 3: Last week of UT on Rails

I’m finally wrapping up my UT on Rails series. While people have been getting close to the end of the course, I’ve gotten the question “Now what?” plenty of times. Now that you’ve spent 40+ hours pouring over videos, exercises, and quizzes where do you go from here? To answer this question I made a short video. But first, the last exercise of the course:

Reddit on Rails: Part 3

This week we wrap up our Reddit on Rails exercise series by adding styling to our project, full text search, and some much needed integration tests. What are you waiting for go start on the exercise.

Where Do We Go Now

A programming course can’t make you a good programmer, watch this video to learn where to go from here. Don’t stop now, you’re so close to doing great things…

Additional Resources


Don’t forget to follow me on twitter @schneems and tumblr. Though the class might be over, I still talk about Ruby and Rails quite a bit. Thanks, and see you on the internets.

Would you like a Mobile App with That?

From Android to iPhone, users everywhere have made it abundantly clear that mobile apps are the future, and when it comes to mobile nothing beats a native experience. Native apps mean we need API’s, and API’s need Authentication. That’s why I’m happy to introduce the solution to your mobile Rails backed authentication needs: oPRO. oPRO (pronounced oh-pro) is a Rails engine for adding an OAuth Provider to any Rails app. OAuth 2.0 is how the web authenticates services, if you’ve ever “signed in with Twitter” or “connected with Facebook” you’ve used OAuth. If you’re new to the concept, check out my introduction to OAuth. Otherwise put your programming cap on, cause we’re going to build your first Rails API backed iPhone app.

The Rails App

I’ll assume you’ve got a Rails app already burning a hole in your pocket, but if you don’t you can easily clone one of mine. The Rails app is going to need a User model that we can authenticate against. You will also need authentication on your User model, oPRO has built-in Devise integration, but if you’re using something else you can easily write your own adapter.

Now that you’ve got a working app you’ll need to install oPRO, you’ll start off by adding this code to your Gemfile:

gem 'opro'

Then run

$ bundle install

and then

$ rails g opro:install

This will put a file in initializers/opro.rb and generate some migrations, and add mount_opro_oauth to your routes. If you are using Devise make sure that the auth_strategy inside of of this initializer is set to :devise, otherwise you’ll need to configure a Custom auth adapter:

config.auth_strategy = :devise

Next we need to migrate the database and we’re almost done.

$ rake db:migrate

This gives us a table to store OAuth client app credentials and a table to store access tokens for our users.

Now we need to configure which controllers will allow OAuth, we do this by adding allow_oauth! to a controller. If you have a UsersController go ahead and add it there, this will give any client with API access the ability to hit any actions in this controller.

class UsersController < ApplicationController
  allow_oauth!
end

The allow_oauth! method accepts the same arguments as a before_filter

Boot, and Configure your First Client App

Now that you’ve got oPRO set up, you need to generate an Client App auth token and secret. This is how your main Rails app will keep track of clients, and can be used for whitelisting, blacklisting and rate limiting. Go ahead and start your local server:

$ rails server

Now with your server running on port 3000 you can view the built in documentation if you wish, but for now we need to visit http://localhost:3000/oauth_client_apps/new to generate a client app. Fill out a name for your app such as: my first API app and hit enter. You should be redirected to a page with a secret and a token. Record these, for the purposes of this example we will use these credentials:

Name:       "my first API app"
client id:  "3234myClientId5678"
Secret:     "14321myClientSecret8765"

Now that you’ve got a working Rails app, and it’s acting as an OAuth provider; it’s time to get this party started and make your first Rails backed iPhone app.

The iPhone App

If you’ve never coded Objective C, don’t get too nervous, I’ve already got an app we can start with. To see the app you can go to https://github.com/opro/opro_rails_demo. First we’ll need to clone this locally, go to your project directory (not inside of your rails app) and clone the repository:

$ git clone git@github.com:opro/opro.git

Move into that directory and run:

$ cd opro_iphone_demo
$ gem install cocoapods
$ pod install
$ open "oPRO-Demo.xcworkspace"

Here we are using cocoapods much like bundler to install external dependencies for our iPhone app. This app relies on the excellent AFNetworking and AFOauth2Client written by @mattt from Heroku. After you’ve run the above, xcode should be open. Make sure the target of the application is set for oPRO-Demo and hit run (cmd+r). You should see a screen like this:

If you don’t see that screen you may need to update Xcode, install the iOS developer libraries, or change your target. Try checking the debug logs for output or errors. If you’re new to iOS programming, I recommend big nerd ranch: iOS Programming as a starting point. The iOS course from code school looks promising.

This iPhone demo app uses a Rails backed oPRO app that I’m hosting on Heroku: http://opro-demo.herokuapp.com. Previously I generated credentials for it that you can see if you open OproAPIClient.h:

#define oClientBaseURLString @"https://opro-demo.herokuapp.com/"
#define oClientID            @"5e163ed8c70cc28e993109c788325307"
#define oClientSecret        @"898ca5b48548bb3988b3c8469081fcfb"

You can make sure the demo works with my default Rails app on Heroku by pressing the “Create a Random User button”, this is will hit an endpoint on https://opro-demo.herokuapp.com/ that saves a new user to the database, and returns the randomly generated email and password so the mobile app can log in. This functionality isn’t something you would want to have in your app, but is useful for an OAuth demo.

Once the server responds to your iPhone simulator, the email and password fields should now be filled-in and the “Log In” button should be active. Press it. This will send the email and password to the server along with your client id and client secret. If everything is successful the server will return an access token you can use on behalf of the user. You should be taken to a new screen that has email, twitter, and zip on it. Try modifying one of the fields and submitting the form. When you do this you are changing data on the Rails server as an authenticated user. From now on, any requests you make with the access token mean you are acting on the behalf of that user.

If you didn’t see the fields update look at the client logs and see if you can find any errors. Now that you’ve got a working iPhone app, it’s time to re-purpose this it for your own site.

Your App, Your Way

Now that you’ve verified that the iPhone demo app works with the demo on Heroku we’re going to modify it to work with your local Rails app. First, make sure that you have your local Rails app running:

$ rails server

Now grab the credentials you wrote down earlier after signing up for a client application on your own server. If you didn’t it’s okay, you can go to http://localhost:3000/oauth_client_apps, select an app, and write down the secret and id, for our purposes we will use these:

Name:       "my first API app"
client id:  "3234myClientId5678"
Secret:     "14321myClientSecret8765"

Remember that your credentials will be different. Now inside of OproAPIClient.h replace “https://opro-demo.herokuapp.com/” with “http://localhost:3000/” and replace the oClientID and oClientSecret with your client and secret. If we were using our example values it would be:

#define oClientBaseURLString @"http://localhost:3000/"
#define oClientID            @"3234myClientId5678"
#define oClientSecret        @"14321myClientSecret8765"

Note: your ID and Secret will be different from these, if you try to use the credentials I have here, it won’t work because your local server is different.

Now that you’ve got your credentials in your iPhone App, re-build it by pressing “run” or hitting (cmd+r). If the app didn’t build check the output from xcode. If everything worked you should see the same screen, but clicking “Create a Random User button should not work. Take a look at your local rails server logs to verify that it is receiving requests from the iPhone simulator. You will receive errors in the log if you are using the “random button”.

Since we can’t create a random user, how will we log in? You’ll need to create a user in your database. If you’re using devise you can visit http://localhost:3000/users/sign_up and enter an email and password. Remember the email and password. If you can’t remember where the sign up form is you can always make a new user in the console:

$ rails console
> password = "password"
> email    = "email@example.com"
> User.create(:email => email, :password => password, :password_confirmation => password)
> User.last.email == email # => true

Now you’ve got a user in your database with an email and password. Enter these into the email and password fields in Xcode. Once you’ve entered both fields you should see the “Log In” button become active. Pull up your rails server logs, and then click the “Log In” button on the iPhone simulator, your should see the request come in with the email you gave, and the password filtered out. If the request went well you should see a 200 status response from the server, and the iPhone simulator will show the user edit page.

If you’re using the demo App I provided, you can change any of those fields and hit enter. You should see the request along with the values you set hit your local server.

Note: the iPhone app expects JSON response from your Rails server under the /users update action, so you might need to add a respond_to block.

If you are running your own app and don’t have a “zip” or “twitter” field in your User table, you will get an error if you hit enter. If that is the case you can open EditUserViewController.m and in the updateUser method you will see that we are creating a dictionary (similar to a hash in Ruby) with “email”, “twitter”, and “zip” fields:

[mutableUserParameters setValue:userEmailField.text forKey:@"email"];
[mutableUserParameters setValue:userTwitterField.text forKey:@"twitter"];
[mutableUserParameters setValue:userZipField.text forKey:@"zip"];

If you don’t want to send the “twitter” and “zip” fields you can take these out so that it is only sending the “email” field:

[mutableUserParameters setValue:userEmailField.text forKey:@"email"];

Save and re-run the iPhone app, re-enter credentials and then try modifying the “email” address of your user. Change it to “schneems@example.com”. When you hit enter you should see the new email come in as a request to your server. When everything works will also be able to see this change in your database:

$ rails console
> User.where(:email => "schneems@example.com")

Congrats, you just made your first working API backed Rails app using OAuth! If you’re still having problems, remember to check your Rails log, and the iPhone simulator log. To log to rails you might use:

puts "something happened!!!!!!!!!!!!!"

But in objective-c you would use:

NSLog(@"something happened!!!!!!!!!!!!!")

We’re not quite done with the demo just yet. We might have authenticated you against your local app, but we don’t want to do this every time, let’s make sure the iPhone app remembers us when we power down the phone.

Remember Me

Getting an access token isn’t much good if we don’t remember it. We’re going to see how we store it on the iPhone and how we can use it to authenticate against later.

Go ahead and stop the iPhone simulator, and restart it by pressing run or hitting (cmd+r). When it comes back online you should notice that the “Log In” button is already active, try hitting it right now. What happens? You should see the update user screen with the same email we put in last time, but how did the app remember? Open up OproAPIClient.m again and take a look at setAuthorizationWithToken (trust me after awhile the method names don’t look so bad). You’ll see that we are storing the accessToken and the refreshToken:

[[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"kaccessToken"];
[[NSUserDefaults standardUserDefaults] setObject:refreshToken forKey:@"krefreshToken"];

Here we are telling our iPhone app to store these values to disk even after the app is killed, or restarted. Then later we can pull those values from disk when we initialize the API client as we do in the initWithBaseURL method:

  NSString *accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"kaccessToken"];
  NSString *refreshToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"krefreshToken"];

  [self setAuthorizationWithToken:accessToken refreshToken:refreshToken];

Now all we have left to do is write some logic in our controller to make the button available if the user authenticated previously. This is done in OproDemoViewController.m

  // Make the log in button clickable if a user has previously authenticated
  if ( [[OproAPIClient sharedClient] isAuthenticated])  {
    [getAccessTokenButton setEnabled:YES];
    [getAccessTokenButton setHighlighted:YES];
    [getUserCredentialsButton setHighlighted:NO];

  }

That’s all there is to it! Now you’ve got an app that can hit your Rails app and act as an authenticated user.

While this might be your first app, you shouldn’t stop here. You can rip out the OproAPIClient.h and OproAPIClient.m to put in your own custom app, or you could modify this one to meet your needs, this is only a starting point. Before we declare victory over our new found API client and Rails app, let’s deploy to production.

To the Cloud!

Now that we’ve got the client working, we’ll put our app on Heroku where anyone can hit the API without needing access to your localhost. If you don’t have an account you’ll need to sign up at Heroku.com. Once you’ve done that you can install the Heroku Toolbelt and then you can provision an app, in the same directory as your rails project run:

$ heroku login
$ heroku create
Creating smooth-rain-2686.. done, stack is cedar
http://smooth-rain-2686.heroku.com/ | git@heroku.com:smooth-rain-2686

Note: your url and app name will be different.

Once you’ve got your Heroku app provisioned, you’ll need to commit the files to git and to deploy. Run:

$ git add .
$ git commit -m "deploy to heroku"
$ git push heroku master

After a successful push, you should see your app compiling and several steps such as bundle install and rake assets:precompile being run. Once it’s done you’ll need to migrate your database:

$ heroku run rake db:migrate

Now you can hit your app and make sure it is working right, visit the url that was given to you earlier, such as http://smooth-rain-2686.heroku.com/. If you have any problems you can check the logs by running:

$ heroku logs --tail

Now that you’ve got your app running in the cloud, let’s add SSL. SSL will protect your app from people snooping on credentials, it will allow encrypted communication using HTTPS between our iPhone and Rails app. There is an SSL add-on you can add to your Heroku app. To provision this add-on you can go to the the add-on page or run this from the command line:

$ heroku addons:add ssl:endpoint

Once your app is safely running on Heroku you can point your iPhone app to your production server in OproAPIClient.h and don’t forget to use https:// instead of simply http://. You can create a new OAuth client app as we did before by visiting your website /oauth/new, then you’ll want to add your id and secret to the OproAPIClient.h as well and save a user to the postgres database on Heroku. To make sure you’re hitting the right url you can always check the server logs on Heroku:

$ heroku logs --tail

Once you’ve got your site running on Heroku and your iPhone client properly configured you can use your very own iPhone app on your very own production Rails app. Pretty cool, huh?

Finishing up

Today you turned your Rails app into an OAuth 2.0 powered API. You made your first native iPhone app and deployed it’s server to production. Not bad for an afternoon’s work. Now that you’ve got the basics you can learn more about how the authorization in the iPhone app works by visiting the oPRO iPhone App Docs. After that you should read about the configuration available visit the oPRO developer’s docs. If you run into any inaccuracies, or you just want to say hi or show of your oPRO powered app, you can always find me on twitter as @schneems. May the OAuth be with you.


Richard works for Heroku on the Ruby Team and teaches rails classes at the University of Texas. If you like APIs as much as he does, chat him up on the twitters @schneems. If you enjoyed this article you might also enjoy raise “hell”: Better Programming through Exceptions.

Database & Rails: Week 9

We are close to wrapping up our 10 week Rails Course. This week we will cover a handful of topics commonly encountered in Rails projects. We then wrap up with part 2 of our Reddit on Rails exercise!

By now you should be hard at work on your personal projects. The students in the course just presented in front of the class with some live demos and a brief intro to to the problems their app were solving. Maybe set aside some time this week to show someone your progress, block off 5 minutes and describe what goal you are working towards, the current state of the project (is it almost done, just getting started, needs UI, etc.), and then show them a quick demo of the app. Explain what type of feedback you are looking for (conceptual, design, usability, etc.) and see what they have to say.

As we are wrapping up the course you need to be focused on learning as much as you can, but also making sure you have the tools to succeed after the class is over.

Rails Cookies and Sessions

Sending Email with Rails

Full Text Search

Background Tasks

Exercise

This week we pick up where we left off last week, building a Reddit clone in Rails: Reddit on Rails part 2

Databases & Rails: Week 8

Welcome back, this week we’re going to tackle some important concepts in Ruby like Dealing with Nil and using Modules in Ruby. We are also going to cover importing data from a spreadsheet, rake, rubygems, bundler, and talk a little about Rail’s testing ecosystem.

Recap of week 7. Then take the Quiz and review the Solutions

Before we get started there have been quite a few questions about why not use a simpler solution than Rails, so I recorded a quick explanation of Simple Versus Hard and why we might want to pick a more complex tool to solve our complex problems

Rails Testing Ecosystem

As your app gets more complex testing components gets even more critical. In this video we cover the basics of what testing does, and then we talk about a few tools we can use to automate tests in our Rails code.

Rubygems & Bundler

Rails is a rubygem, but what is a rubygem? We’ll cover that in this video as well as exactly what bundler does, and why we should always keep the Gemfile and Gemfile.lock in our source control.

Import data into Rails from a Spreadsheet

By popular demand learn how to read spreadsheet data into Ruby and then put it in Rails.

Intro to Rake

Rake is a useful command line tool, learn how to write your first rake task and how to use Rake together with Rails.

Dealing with Nil

As a Ruby programmer the most common value you’ll encounter will be nil. It’s our duty to be on constant watch for nil and make sure it doesn’t reek havoc on our code. This video will introduce you to some boolean logic we can use to defend against the tyranny of nil. We’ll then cover using nil? and empty? as well as several custom Active Support methods we can use from Rails to help guard against nil. Nil isn’t all bad, at the end we’ll see how we can use this functionality of nil to populate variables only if they don’t exist. We’ll use this to find or create a user in Rails.

Using Modules in Ruby

Modules are an extremely important part of the Ruby ecosystem. Learn how to mix in methods into a Ruby class using modules in this introductory video.

Exercise

This week we’ll start a Hero’s journey to build a site similar to Reddit. You’ll need to use everything we’ve learned so far. This isn’t a follow along copy and paste tutorial, this is how I work when I’m making websites. Good luck, you’ll need it. Building Reddit on Rails.

Get Previously Saved Changes in Rails

Some times you need to see what fields changed in an object in Rails. I’ve known for awhile that you could do this before an object saved:

user = User.last
user.name = "schneems"
puts user.name_changed?
# => true

puts user.changes
# => {"name"=>["richard", "schneems"]} 

but as soon as you save the object to the database you lose all that goodness.

user.save
puts user.name_changed?
# => false 

puts user.changes
# => {}

What if we wanted to get the changes before those values were committed? We can use the previous_changes method!

user.save
puts user.name_changed?
# => false 

puts user.previous_changes
# => {"name"=>["richard", "schneems"], "updated_at"=>[Tue, 31 Jul 2012 18:53:12 UTC +00:00, Tue, 31 Jul 2012 18:56:49 UTC +00:00]} 

It’s that simple. Go forth and make changes with impunity! Your previous results will be available when you need them.

(This only works when the object is still in memory, if you pull a user from the database changes and previous_changes will both be blank).

Active Record Deep Dive

If you’re new to Rails and Active Record, or you’ve been using them for some time, there are likely methods you’ve been overlooking. This week I take a look at the most common SQL Query interfaces for Active Record. Finally we wrap up by talking about how Active Record allows us to chain together methods, how we can prevent SQL injection attacks on our websites, and how to read Ruby Documentation.

Watch the video Recap of last week and take the quiz before looking at the solutions.

Feel free to skip around, most of the videos are self explanatory. This is week 7 of my Databases & Rails course taught at the University of Texas. If you’re new to databases you might want to start out with Why and how to use a database, and if you’re not familiar with Active Record Relationships you will get more out of this if you watch modeling relationships first.

Active Record: Where

With a Active Record we can use where to pull data from our database using a set of criteria. We can use a hash syntax, insert plain SQL, or use a query string escaped syntax. The where method can be used to return back objects or a collection of objects from the database.

Active Record: Includes

Active Record: includes helps us to eager load data where appropriate and avoid N+1 query problems.

Active Record: Find

Using Find in Active Record is much like where but only looks up via primary key. If the record is not found an error will be raised.

Active Record: Order

The order of your data can be controlled in Active Record using the order method.

Active Record: Limit

Sometimes we don’t want to return too much data, when we have a large dataset we can use limit to decrease our results.

Active Record: Offset

Imagine you’re an online retailer like Amazon if someone is looking for frying pans, you’re not going to show them every frying pan you have on one page, it would be hard to look at, and wreak havoc on your server. You can use offset and limit together to “paginate” data. That is only showing 20, 50, 100, etc. items per page.

Active Record: Joins

Understanding joining data is the foundation of building and traversing databases. Learn the concepts behind joining two tables and the differences between an inner and outer join. If you’re new to the concept of has many or belongs to you should watch the videos from week 2 modeling relationships with Active Record.

I came to Rails with no database background, learning to effectively understand and leverege joins has made a tremendous impact on the performance and quality of code i’m able to write in Rails.

Active Record Group

We can group together similar terms inside of our database, we can use this for performing aggregate calculations, or for limiting search results to one result per grouped attribute.

Active Record: Having

Possibly one of the most confusing methods of the set, having is used to query against aggregated results. Typically having and group are used together. Having can be very useful when getting metrics about your data. For example if you have a user model, a course model, and a role model so that users can sign up to take courses through roles then we might want to see the average number of courses users have taken. We can do this with having.

Just in Time SQL Queries with Active Record

The interface for Active Record has improved dramatically since the early days of rails. See the mechanism behind how we are able to chain together methods to produce SQL queries, and how this same mechanism protects against un-used sql queries from taking up too much time on a page.

Preventing SQL Injection Attacks

As even XKCD knows, SQL injection is an all to real danger to database backed software. Learn how to craft a SQL injection attack inorder to protect your own code by using safe Active Record practices.

Reading Ruby Documentation

Quite possibly the most important skill of any Ruby programmer, reading documentation effectively is critical. We’ll take a look at the Ruby docs for Array which will help quite a bit with the exercise. Sometimes we might want to manipulate the results of our data set after we’ve gotten it back from the database, since returning a collection of objects will return as an Array in Rails, we can

If you liked the videos please take a moment to subscribe to my youtube channel, follow me, @schneems, on twitter, or subscribe to my tumblr blog. If you know someone learning rails for the first time or just looking to get better, a referral to this material would make a huge difference. Thanks for sticking around and have a great week!

Exercise

Use the docs to get the tests to pass for Arrays, Active Record and Hashes

Databases & Rails: Week 5 Controllers

We’ve covered models, views, routing, and briefly introduced controllers. This week we’re taking the deep dive into controllers, talking about what they can do, and how we want to use them. Last week we talked about wiring things together with routing. You can watch the Recap then do the Quiz and once you’re done check out the Quiz Solution.

Before we get started talking about controllers, first we’ll introduce Ruby Variable Scope. We’ve used local variables and constants in our code, and now it’s time to introduce instance variables and discuss their differences, and why you might want to use one over another.

Now that you’ve seen how we can use instance variables, we will use one in our controller to move some SQL logic from the view to the controller. This is important for keeping our views clean and focused on presentation logic. It will also help us later when we look into the other things a controller can do.

Database logic in controllers

Now that we’re pulling data from our database in our controller we can render, redirect Filter & Format from our controllers. Check out this video to find out what these are and how we can use them to help build our app.

This last video on Rails URL Helpers covers using $ rake routes to get info on routes and how we can use different url helpers in our app.

In the exercise we’ll be nesting a few if, def and class definitions in our code. It can be easy to lose your place and difficult to remember what end corresponds to which line. To help out you can watch a quick video on my End of the line, programming trick with the sublime text editor.

Exercise

In this exercise we’re fleshing out the app we worked with later to add full CRUD and move logic from the view to the controller. Just fork and clone the repo and go through the readme!

Thanks for following along, for up to date ruby info you can catch me @schneems, and can subscribe to my youtube channel

Databases & Rails: Week 3 Pure Ruby Views

In week one we learned about storing data and using databases. In week 2 we saw how we can model relationships with databases, and use those relationships with Ruby and Active Record to build models in Rails. This week we start out with a quick Recap of last week followed by a Quiz. Once you finish the quiz you can check out the Quiz Solutions.

This week we will be focused on building cool things with Pure Ruby (no Rails). We’re going to cover some Ruby basics, and then dive into an exercise where we build an HTML generator using only Ruby. The students really enjoyed the exercise, and got quite a bit out of it, so you shouldn’t skip it. Even if you’ve been using rails for years, the exercise might give you new insight into how exactly some of that Rails magic works.

We’ll also cover using GIT and you’ll need that for the exercise. Get ready cause here comes some serious learning.

Week 3 Videos

Introduction of topics covered:

Ruby arrays and iterating over them with each and map methods:

Using the functions found in Ruby’s STDlib:

Using the ERB library from Ruby’s STDlib to generate HTML:

Finally an Introduction to using GIT. We cover the basics of using a source control management software (GIT) as well as the mechanics of saving files, adding them to a repo, and committing them. GIT is a valuable skill to have, and is needed for the exercise.

Week 3 Exercise

First you need to Fork and Clone my Generating HTML views with pure Ruby repository . Then you can follow along with the exercises in the readme.

If you’re thinking about skipping the exercise, don’t. Programming is a language that you have to learn by using it. As always if you get stuck try googling, or posting onto StackOverflow.

The only difference is that I won’t be grading your work, so don’t submit a pull request when you’re done.

Good luck and happy coding.

Fin

Next week we’ll be putting what we learned about databased backed models and view generation together to start building a fully functional app. Stay tuned, subscribe to this tumblr blog, or youtube channel and let me know if you’ve got any comments @schneems

Next page Something went wrong, try loading again? Loading more posts