Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Build a Todo List Application with Rails 4 Build a Todo List Application with Rails 4 Creating Methods in Tests

Don't understand why this code works

def create_todo_list(options={})
        options[:title] ||= "My todo list" #means if we don't send in a title, it will be "My todo list". If we do send one in, it'll be that.
        options[:description] ||= "This is my todo list."

        visit "/todo_lists"
        click_link "New Todo list"
        expect(page).to have_content("New todo_list")

        fill_in "Title", with: options[:title]
        fill_in "Description", with: options[:description]
        click_button "Create Todo list"
    end

    it "redirects to the todo list index page on success" do
        create_todo_list
        expect(page).to have_content("My todo list")
    end

    it "displays an error when the todo list has no title" do
        create_todo_list(title: "")
        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("This is what I'm doing today.")
    end 

Here's how I understand it: on the first line, the create_todo_list takes one argument, called 'options'. If no argument is sent in to the method, the argument 'options' becomes an empty hash by default.

Let's say we run simply create_todo_list. A key called :title is created in the hash, and its value is "My todo list". Another key, :description, is created, and is given a value of "This is my todo list."

I get that, and how the rest of the method runs after that.

Now, here, we run: create_todo_list(title: "")

I don't get why this works. I would have thought the argument needs to be like this: create_todo_list({:title => ""})

But this doesn't work.

Don't we need to create a hash with a key of :title and a value of "", for the argument, in order for the method to work?

How does title: "" create a hash with a key of :title and a value of ""?

It's a shorthand you can use key: 'value'

This helps : http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals

That ALMOST hits the spot, Mike. Solid link, thanks!

However, in that wikibook they say that:

hash = { symbol: 1 }
# => { :symbol => 1 }

But in my code it's run inside an argument with no curly braces:

create_todo_list(title: "")

So, is it simply the case that this means:

create_todo_list( { :title => "" } )

?

EDIT: well, I should have done this before....! I played around with a little test file and:

def method(options)
    puts options
end

method(title: "value")

=> {:title => "value"}

So, there's our answer. It's simply shorthand, BUT I WISH THEY'D TOLD ME THAT IN THE TUTORIAL!!

I know too much handholding is a bad thing, but in the Ruby tutorials in Treehouse, I've found that they fail to explain little things like this that are so confusing for a beginner.

I even completed the entire Ruby Foundations (or whatever it was called) - it was a beast, and they didn't cover shorthand like this. And shorthand like this is REALLY REALLY common in Rails.

Come on, Treehouse, where do you cover shorthand in your tutorials?

2 Answers

I made a blog post about this here: http://rubywarriors.com/2014/12/05/shorthand-way-to-pass-a-hash-into-a-method-as-an-argument-symbols-for-keys/

(this may be a shameless plug, but it IS a good summary of the above!)

This was taught in Ruby Foundations.

http://teamtreehouse.com/library/ruby-foundations/ruby-core/symbols

@1:55