Skip to content

WIP - Adding a scaffold-free version of Suggestotron #649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/step.rb
Original file line number Diff line number Diff line change
@@ -195,6 +195,7 @@ def todo todo_text
IRB_CAPTION = "Type this in irb:"
RESULT_CAPTION = "Expected result:"
FUZZY_RESULT_CAPTION = "Approximate expected result:"
RAILS_CONSOLE_CAPTION = "Type this in the Rails console:"

def console(commands)
console_with_message(TERMINAL_CAPTION, commands)
@@ -211,6 +212,10 @@ def console_without_message(commands)
console_with_message("", commands)
end

def rails_console(commands)
console_with_message(RAILS_CONSOLE_CAPTION, commands)
end

def irb msg
div :class => "console" do
span IRB_CAPTION
7 changes: 7 additions & 0 deletions sites/suggestotron-sans-scaffolds/_consider_deploying.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
div :class => "deploying" do
h1 "Deploying"
blockquote do
message "Before the next step, you could try deploying your app to Heroku!"
link 'deploying_to_heroku'
end
end
10 changes: 10 additions & 0 deletions sites/suggestotron-sans-scaffolds/_switch_to_home_directory.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
message "`cd` stands for change directory."

option "Windows" do
console "cd c:\\Sites"
message "`cd c:\\Sites` sets our Sites directory to our current directory."
end
option "Mac or Linux" do
console "cd ~"
message "`cd ~` sets our home directory to our current directory."
end
9 changes: 9 additions & 0 deletions sites/suggestotron-sans-scaffolds/add_a_new_topics_form.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
message <<-MARKDOWN

This page will walk through adding a form to create topics. FORM HELPERS!

This is probably a good time to talk about HTTP verbs and RESTful routing.

MARKDOWN

next_step "add_an_edit_topics_form"
78 changes: 78 additions & 0 deletions sites/suggestotron-sans-scaffolds/add_a_topics_index.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
section "Overview" do
message <<-MARKDOWN
Now let's add a view!

Things to cover:

* Getting resources from the DB via the controller
* Sharing those with the view
* ERB
MARKDOWN
end

steps do
step do
message <<-MARKDOWN
First, let's add the correct view. Under views, add a folder called `topics`. Within that folder, make a file
called `index.html.erb`
MARKDOWN
source_code "<h1>This is a topics index!!!</h1>"
message <<-MARKDOWN
View file structure description & how they're named the same as the controller actions
MARKDOWN
end

step do
message <<-MARKDOWN
Go to the browser and look at your beautiful page
MARKDOWN
end

step do
message <<-MARKDOWN
Now we'll actually show the topics on the page. First, we need to get all the topics out of the database.

Update your controller!
MARKDOWN
source_code <<-RUBY
def index
@topics = Topic.all
end
RUBY
message <<-MARKDOWN
Now we're getting the stuff from the controller
MARKDOWN
end

step do
message <<-MARKDOWN
Lets show it on the page. Add this to your view, `app/views/topics/index.html.erb`.
MARKDOWN
source_code <<-RUBY
<%= @topics %>
RUBY
message <<-MARKDOWN
Wow, that's ugly! I guess we're not done. ERB!!
MARKDOWN
end

step do
message <<-MARKDOWN
Let's show all the topics! Remove that ugly line, and replace it with this:
MARKDOWN
source_code <<-RUBY
<% @topics.each do |topic| %>
<h2><%= topic.title %></h2>
<p><%= topic.description %></p>
<% end %>
RUBY
message <<-MARKDOWN
MARKDOWN
end
end

section "Recap" do
message "This is a recap"
end

next_step "add_a_new_topics_form"
59 changes: 59 additions & 0 deletions sites/suggestotron-sans-scaffolds/add_a_topics_model.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
section "Overview" do
message <<-MARKDOWN
Now that we have a place to save our topics in the database, we need to create a Ruby class to represent
our topics &mdash; a model.
MARKDOWN
end

steps do
step do
message <<-MARKDOWN
Add a new file inside the directory `app/models`. In Sublime, you can right click (ctrl + click on Mac)
and select "New File". Save it as `topic.rb`.
MARKDOWN
end

step do
message "Add the following code to that file:"
source_code <<-RUBY
class Topic < ActiveRecord::Base
end
RUBY
message <<-MARKDOWN
This creates a class called Topic that inherits from ActiveRecord::Base. (Don't forget to save!)
MARKDOWN
end

step do
message "Now we're going to make sure we hooked up our model correctly, using the Rails console!"
console "rails console"
message "You're now in an interactive terminal, just like IRB, but with all of your Rails app loaded up!"
end

step do
rails_console "Topic"
message "This will tell you what Rails knows about the model Topic, something like: "
source_code "=> Topic(id: integer, title: string, description: text)"
end

step do
rails_console 'cats = Topic.new(title: "Cats are so great", description: "Yay cats!")'
message "This creates a new topic in the database, but it's not saved yet. See how it doesn't have an id?"
source_code '=> #<Topic id: nil, title: "Cats are so great", description: "Yay cats!">'
rails_console 'cats.save'
rails_console 'cats'
message "Now we have a saved topic &mdash; you can see it now has an id:"
source_code '=> #<Topic id: 1, title: "Cats are so great", description: "Yay cats!">'
end

step do
message "Make two or three more topics so that you have something to look at once you make a web interface!"
end

step do
rails_console "Topic.all"
message "Look at all your topics! Neat!"
end
end

next_step "add_a_topics_routes_and_controller"
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
section "Overview" do
message <<-MARKDOWN
We're going to an index, so we can see all of our beautiful topics!

### Reviewing MVC
This is a review of MVC
MARKDOWN
end

steps do
step do
message <<-MARKDOWN
First, we're going to update the `routes.rb` file, inside the `config` directory. This file comes
with lots of helpful comments that can help you create your routes correctly. We're going to add our
routes using the resource method on line 2:
MARKDOWN
source_code <<-RUBY
resources :topics
root 'topics#index'
RUBY
message <<-MARKDOWN
This is helping information about routes. Mention something about the root route.
MARKDOWN
end

step do
message <<-MARKDOWN
Now let's look at what routes that generated by visiting http://localhost:3000/rails/info/routes.

Here's some info about reading that page
MARKDOWN
end

step do
message <<-MARKDOWN
Okay, let's go look at our app again and see what's changed. Visit http://localhost:3000.

Now, instead of the default Rails page, we see the error "uninitialized constant TopicController" ... because
there's no controller for topics!
MARKDOWN
end


step do
message <<-MARKDOWN
Time for a topics controller
MARKDOWN
source_code <<-RUBY
class TopicsController < ApplicationController
def index
end
end
RUBY
message <<-MARKDOWN
What does this do? How does it relate to the route?
MARKDOWN
end
end

section "Recap" do
message <<-MARKDOWN
This is a recap
MARKDOWN
end

next_step "add_a_topics_index"


message "# here's the original 'set root route' page content"

goals {

goal "Now that the structure is complete, let's make the flow work smoothly."

message "Currently when you go to <http://localhost:3000> you see the \"Welcome
aboard\" message."

message "It would be easier to use our app if <http://localhost:3000> went directly to the topics list."

message "In this step we'll make that happen and learn a bit about routes in Rails."
}

steps {

step "Add a root route" do
message "Open `config/routes.rb`. Search the file for 'root' (near the top) uncomment that line and change it to read `root 'topics#index'`. When you are done the line should look like this:"

message "(Rails 3.x users should add `root to: 'topics#index'` and will need to remove their `public/index.html` file)."

end

source_code :ruby, <<-RUBY
root 'topics#index'
RUBY


step "Confirm your changes" do
message "Go back to <http://localhost:3000/>. You should be taken to the topics list automatically."
end
}

explanation {

message <<-MARKDOWN
* `root 'topics#index'` is a rails route that says the default
address for your site is `topics#index`. `topics#index` is the topics
list page (the topics controller with the index action).
* Rails routes control how URLs (web addresses) get matched with
code on the server. Similar to how addresses match with houses and
apartments.
* The file `config/routes.rb` is like an address directory listing the
possible addresses and which code goes with each one
* `routes.rb` uses some shortcuts so it doesn't always show all the
possible URLs. To explore the URLs in more detail we can use the
terminal.

At the terminal type `rake routes`. You should get something that
looks like this:

````
$ rake routes

Prefix Verb URI Pattern Controller#Action
topics GET /topics(.:format) topics#index
POST /topics(.:format) topics#create
new_topic GET /topics/new(.:format) topics#new
edit_topic GET /topics/:id/edit(.:format) topics#edit
topic GET /topics/:id(.:format) topics#show
PATCH /topics/:id(.:format) topics#update
PUT /topics/:id(.:format) topics#update
DELETE /topics/:id(.:format) topics#destroy
root GET / topics#index
````
This shows all the URLs your application responds to. The code that starts with colons are variables so :id means the id number of the record. The code in parenthesis is optional.

In Rails 4, you can also get this information on your site in development. Go to <a href="http://localhost:3000/rails/info">http://localhost:3000/rails/info</a> and you'll see something like this:

<img src='img/rails4_rails_info_routing.png'>

You'll also see that table in Rails 4 whenever you try to access an invalid route (try <a href="http://localhost:3000/sandwich">http://localhost:3000/sandwich</a>)

### Exploring Routes (optional)

Now you can have a look at the paths that are available in your app.
Let's try looking at one of the topics routes we just generated.
Open up your rails console and play:

$ rails console
>> app.topics_path
=> "/topics"
>> app.topics_url
=> "http://www.example.com/topics"

`app` is a special object that represents your entire application.
You can ask it about its routes (as we just did), play with its
database connections, or make pseudo-web requests against it with
`get` or `post` (and lots more).

MARKDOWN
}

76 changes: 76 additions & 0 deletions sites/suggestotron-sans-scaffolds/add_a_topics_show_page.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
message <<-MARKDOWN
Turns out the descriptions are getting too long for the index page, and we need to hide them!

Students will:

* Add a show action to the controller
* Add a show view
* Change the index to just display the title w/a link to the view

MARKDOWN

next_step "redirect_to_the_topics_list_after_creating_a_new_topic"


message "# Here's the old page for linkifying the title"

goals {
message "Your friends recommended two changes for the site:"
goal "Don't show the description on the list page"
goal "Make the title a link and when it's clicked show the description"
}

steps {


step("Remove the description") {

message "Let's start by removing the description. Open `app/views/topics/index.html.erb` and delete the line that looks like this:"

source_code :erb, "<td><%= topic.description %></td>"

message "Also delete the line that looks like this:"
source_code :erb, "<th>Description</th>"

message "If you save and try to load it in the browser you should see that the description no longer appears."

}

step("Make the title a link") {

message "Now make the title a link by editing `app/views/topics/index.html.erb` (again) and replacing this line:"

source_code :erb, "<td><%= topic.title %></td>"

message "with this:"

source_code :erb, "<td><%= link_to topic.title, topic %></td>"
}
}

explanation {

source_code :erb, "<td><%= topic.description %></td>"

message "This line was getting the description using .description and just printing it out."

source_code :erb, "<th>Description</th>"

message "
`<th>` stands for table header and everything between `<th>` and
`</th>` was being printed as a table header (bold). We removed it
since we removed the description and it would look funny to have the
header and the wrong thing below it."

hr

source_code :erb, "<td><%= link_to topic.title, topic %></td>"

message "
Here's another use of `link_to` to create a link on the page. This
`link_to` creates a link using the text from the topic title and goes
to the topic#show page."
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
message <<-MARKDOWN

This page will have the student pull their topics form into a partial and render it on the edit page.

This will also involve adding edit and update actions to the topics controller.

MARKDOWN

next_step "add_topic_voting"
84 changes: 84 additions & 0 deletions sites/suggestotron-sans-scaffolds/add_topic_voting.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
message <<-MARKDOWN
This page is going to have students:

* write a migration to add "vote_count" to the topics model
* add vote buttons to the UI with relevant controller actions

MARKDOWN

next_step "add_a_topics_show_page"

message "## This is the old page, for reference"

goals {
goal "Now we're going to add a button people can click to cast a vote."
}

steps {

step "Add the button to the view" do

message "Edit `app/views/topics/index.html.erb` so that the bottom loop looks like this:"

source_code :erb, <<-HTML
<% @topics.each do |topic| %>
<tr>
<td><%= topic.title %></td>
<td><%= topic.description %></td>
<td><%= pluralize(topic.votes.count, "vote") %></td>
<td><%= button_to '+1', votes_path(topic_id: topic.id), method: :post %></td>
<td><%= link_to 'Show', topic %></td>
<td><%= link_to 'Edit', edit_topic_path(topic) %></td>
<td><%= link_to 'Destroy', topic, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
HTML
end

step "Add the create method to the controller" do
message "Add the following method to `Vote` in `app/controllers/votes_controller.rb`:"
source_code :ruby, <<-RUBY
class VotesController < ApplicationController
def create
topic = Topic.find(params[:topic_id])
vote = topic.votes.build
vote.save!
redirect_to(topics_path)
end
end
RUBY
end

step "Confirm your changes in the browser" do
message "Go back to <http://localhost:3000/topics> and play."
message "Revel in the fact that you didn't have to restart the server to see these changes. Hawt, no?"
end
}

explanation {

message "First we added these two lines to `app/views/topics/index.html.erb`"
source_code :erb, <<-HTML
<td><%= pluralize(topic.votes.count, "vote") %></td>
<td><%= button_to '+1', votes_path(topic_id: topic.id), method: :post %></td>
HTML

message <<-MARKDOWN
* `pluralize(topic.votes.count, "vote")` displays the number of votes the topic has, plus the word 'vote' or 'votes' accordingly.
* `button_to '+1'` creates an html button with the value '+1'.
* `votes_path(topic_id: topic.id)` creates the right url for the action we want to invoke. In this case, we want to create a vote for the current topic.
* `votes_path(topic_id: 42)` would output `/votes?topic_id=42`
* `method: :post` ensures we do the create action of CRUD, not the read action.

The changes we made to votes controller are a bit more complicated so let's work through them line by line.

* `topic = Topic.find(params[:topic_id])`
* Finds the topic in the database with that id and stores it in the variable 'topic'.
* `params[:topic_id]` corresponds to the topic_id part of the votes_path above (eg `?topic_id=42`).
* `vote = topic.votes.build` creates a new vote for the current topic.
* `vote.save!` saves the vote to the database.
* `redirect_to(topics_path)` tells the browser to go back to topics_path (the topics list).
MARKDOWN
}

insert 'consider_deploying'
73 changes: 73 additions & 0 deletions sites/suggestotron-sans-scaffolds/creating_a_migration.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
section "Overview" do

model_diagram header: 'Topics', fields: %w(id title description)

message <<-MARKDOWN
Suggestotron has a list of topics that people can vote on. We'll store our topics in the database.

Rails communicates with the database using Active Record, which allows us to write Ruby code instead of SQL.
We change our database using a migration file.

### What's a migration?

Migration files allow you to recreate the state of the database from scratch at any point. When you run `rake db:migrate`, Rails
goes through each of the files in the `db/migrate` directory to create all the tables in the database.

Here is a fun tip: DON'T UPDATE MIGRATION FILES. It's terrible, albeit initially tempting, practice to realize you need another field and edit
the original migration file. Instead, create a new migration (perhaps called `AddVotesToTopics`). This will keep your database
in a reasonable state and not ruin everything if you're ever collaborating with other developers on a project.
MARKDOWN
end

steps do


step { console "rails generate migration AddTopics" }

step do
message <<-MARKDOWN
In your text editor, find the file that you just generated. It will be in the folder `db/migrate`
and will end with `_add_topics.rb` (the first part is a timestamp). Double click on the file to
open it in Sublime.
MARKDOWN
end

step do
message <<-MARKDOWN
Now we'll tell ActiveRecord what we actually want the table to look like. Rails has given us
`up` and `down` methods already, but we can actually combine all of our commands into a single method, `change`.

Add the following text to your migration, replacing lines 2 through 6:
MARKDOWN
source_code <<-RUBY
def change
create_table :topics do |t|
t.string :title
t.text :description
t.timestamps
end
end
RUBY
message <<-MARKDOWN
ActiveRecord will add the id to the table automatically, so we only have to specify the title and description.
MARKDOWN

end

step do
console "rake db:migrate"
message <<-MARKDOWN
This tells Rails to update the database to include a table for our new model. Rails is also smart enough to create the database if it can't find it.
MARKDOWN
end
end

section "rake" do
message <<-MARKDOWN
`rake` _(Ruby Make)_ is a tool that allows you to run small Ruby programs (**tasks**) that you use often in your application. Here, `rake db:migrate` is a task provided by the Rails framework.

You can run `rake -T` to see a list of all the `rake` commands your app currently responds to, along with a short description of each task.
MARKDOWN
end

next_step "add_a_topics_model"
36 changes: 36 additions & 0 deletions sites/suggestotron-sans-scaffolds/credits_and_next_steps.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
message <<MARKDOWN
Guess what? _**You're done!!!**_ Congratulations, you just \"finished\" your first rails app!

(They're never _really_ ever finished... have fun tweaking it!)

# Extra Credit

If you got all the way through Suggestotron with some time to spare, here's some extra stuff you can try:

* Add a downvote button that does the opposite of what the upvote button does
* Sort topics by their number of votes
* Add an 'about' page, linked from the bottom of the Suggestotron topics list. Link back to the Topics list from the About page so users don't get stranded.

MARKDOWN

h1 "Authors"

ul do
li "Sarah Allen"
li "Sarah Mei"
li "Alex Chaffee"
li "Ryan Davis"
li "Steven! Ragnarok"
li "...and many, many others"
end

h1 "What next?"

ul do
li "Probably time for the closing presentation."
li "After that, start a project, tutorial, and come back again!"
li do
span "All our favorite resources can be found on the RailsBridge site: "
a "http://railsbridge.org/learn/resources", href: "http://railsbridge.org/learn/resources"
end
end
111 changes: 111 additions & 0 deletions sites/suggestotron-sans-scaffolds/deploying_to_heroku.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
h2 do
span "If you haven't yet deployed to heroku, start at "
a 'First-time setup', href: '#first-time'
span ". Otherwise, start at "
a 'Every time', href: '#every-time'
span "."
end

a name: 'first-time'
situation "First-time setup" do
step "Create a heroku application" do
console "heroku create"
message "`heroku create` registers a new application on heroku's system. You should see some output including your new app's URL."
end

step "Edit the Gemfile" do
important "Each application has its own `Gemfile`. Be sure you're opening the one inside your app's folder."

message "Heroku will run our application slightly differently than our development computer does, which requires us to make a small change to our `Gemfile`."

message "Open the file called `Gemfile` in Sublime Text, or your preferred editor, and find the line containing:"

source_code :ruby, <<-RUBY
gem 'sqlite3'
RUBY

message "**Remove that line** and replace it with:"

source_code :ruby, <<-RUBY
group :development, :test do
gem 'sqlite3'
end

group :production do
gem 'pg'
gem 'rails_12factor'
end
RUBY
end

step "Apply the Gemfile changes" do
console "bundle install --without production"
message "Every time the Gemfile changes, you need to run ``bundle install`` for the changes to be processed. The processed version of the changes is stored in another file called ``Gemfile.lock``."
end

step "Commit the Gemfile changes" do
message "There are now changes to Gemfile and Gemfile.lock that need to be committed before we can push to heroku."
console <<-SHELL
git add .
git commit -m "Changed Gemfile for heroku"
SHELL
tip "There is a period after the word add in the first line."
end
end

a name: 'every-time'
situation "Every time" do
step "Commit any pending changes to git" do
message "Heroku will only receive the files we've committed into our local git repository. So we need to make sure all changed files have been committed."
console "git status"
message "`git status` shows you any pending changes you've created. If it has no output, you're already ready to deploy! Otherwise..."

console <<-SHELL
git add .
git commit -m "Some helpful message for your future self"
SHELL
message "Your commit message should reference whatever your outstanding changes are: something like 'added votes to the topics index'."
end

step "Push changes to heroku" do
console "git push heroku master"
message "This takes all changes you've committed locally and pushes them to heroku."
end

step "Run database migrations on Heroku" do
console "heroku run rake db:migrate"
message "This tells Heroku to run your migrations on its database, like running rake db:migrate locally. Heroku's database is separate from the one on your computer, which means it needs to be updated every time you make changes to the structure of your database. It also means that you'll not see any of the data you entered into the sqlite3 database on your computer."
end

step "Visit your application" do
console "heroku open"
message "This opens the new application in your browser."
end
end

explanation do
message <<-MARKDOWN
First, we had to do some work to make Heroku happy with our application. This required updating the Gemfile and bundling.

* The Gemfile is a list of all the Ruby libraries your application needs.
What we've declared here is that we want to use the `sqlite3` library
while we're developing on our computer (the development group) but when
deploying to heroku (the production group) we want to use the `pg` library,
which is made for the type of database that heroku uses.

* Bundler is how Ruby projects keep track of the gems that they use. We told
bundler what we wanted to use in the `Gemfile`, now we need to make sure those
gems are installed. Since we don't have the type of database heroku does, we
skip the production gems. Don't worry though! Bundler still logs them so
Heroku will install them when they get your code.
MARKDOWN

message "You should be able to deploy your application any time it's in a good, working state. Your typical workflow will look like:"
img src: "img/workflow.png", alt: "workflow", style: "border: none"
ol do
li { message "Add or change some code" }
li { message "Commit your changes (`git commit`)" }
li { message "(repeat)" }
end
message "Any time your changes are committed, you should feel free to `git push heroku master` and boom! Your changes are live!"
end
107 changes: 107 additions & 0 deletions sites/suggestotron-sans-scaffolds/getting_started.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
section "Overview" do
message <<-MARKDOWN
### What is Rails, again?
Rails is a framework for creating web applications using the Ruby programming language.

### What's a framework?
Most web apps have the same set of problems, like how to store data and how to get HTML to the browser.
A framework is a set of files that can be used to build any kind of web app, so that as a
developer you can focus on the unique functionality of your app, which is known as the business logic.

### What this step is about:
We're going to get into a directory (which is another word for folder) and make a new Rails app,
with just three words.
MARKDOWN
end

steps do

tip "If you have _any_ problems, contact a TA immediately."

step do
insert 'switch_to_home_directory'
end

step do
message "If this is your first workshop, create a directory for your work."
console "mkdir railsbridge"
end

step do
console "cd railsbridge"
end

step do
console "rails new suggestotron-sans-scaffolds"
message "'rails new' creates a new rails project with the name you give."
message "In this case we told it to create a new project called `suggestotron-sans-scaffolds`. We'll go into detail on what it created shortly."
end

step do
console "cd suggestotron-sans-scaffolds"
message <<-MARKDOWN
Review: `cd` stands for change directory.


`cd suggestotron-sans-scaffolds` makes suggestotron-sans-scaffolds our current directory.
MARKDOWN
end

step do
console "ls"
message "'ls' stands for 'list (stuff)'."
message "It shows you the contents of the current folder."
end

step do
message <<-MARKDOWN
Open your application in your text editor. In Sublime, you can do this by going to File, Open, and
navigating to your project folder. Click on the project folder so it's highlighted (don't go into the folder), then click on the Open button.


Make sure you can see the file structure in the left
nav, like so in Sublime:
MARKDOWN

img src: "img/rails-new-open-in-sublime.png", alt: "A new Rails app open in Sublime Text 2"


end

message <<-MARKDOWN
### What did that do?
You can see that <code>rails new</code> created a lot directories and
files. We're going to focus on a few of them today:
MARKDOWN

table border: "1", cellspacing: "0", cellpadding: "3", align: "center" do
tr {
th "File/Folder"
th "Purpose"
}
tr {
td "app/"
td "Contains the controllers, models, and views for your application. You will do most of your work here."
}
tr {
td "config/"
td "Configure your application's runtime rules, routes, database, and more."
}
tr {
td "db/"
td "Shows your current database schema, as well as the database migrations."
}
tr {
td "public/"
td "The only folder seen to the world as-is. If you put files in here, they will be served directly without any processing by Rails."
}
tr {
td "app/assets/"
td "This is where your images, JavaScript, stylesheets (CSS), and other static files should go. Rails apps use something called the Assets Pipeline, which combines all the JavaScript and CSS files in this directory into a single file for speediness."
}
end

message "There is a lot more that `rails new` created. Probably enough to fill a book, so we're going to ignore them for now."
end

next_step "start_using_git"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sites/suggestotron-sans-scaffolds/img/mvc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
goals {

message "
When a user creates a new topic they are currently shown a page with
just that topic. For our voting app it makes more sense that they
would be taken back to the topic list."

goal "In this step we'll change the flow of our app so that the user is taken back to the topics list after they add a new topic."
}

steps {

step "Change the topics controller" do

message "Open `app/controllers/topics_controller.rb` and look at the create method. "

message "Find the line:"

source_code :ruby, "format.html { redirect_to @topic, notice: 'Topic was successfully created.' }"


message 'and change `@topic` to `topics_path` like this:'

source_code :ruby, "format.html { redirect_to topics_path, notice: 'Topic was successfully created.' }"

message 'so that the file looks like this:'

source_code :ruby, <<-RUBY
def create
@topic = Topic.new(topic_params)

respond_to do |format|
if @topic.save
format.html { redirect_to topics_path, notice: 'Topic was successfully created.' }
format.json { render json: @topic, status: :created, location: @topic }
else
format.html { render action: "new" }
format.json { render json: @topic.errors, status: :unprocessable_entity }
end
end
end
RUBY
end

step "Add the flash message to your application view" do
message "Open `app/views/layouts/application.html.erb`."

message "Find the `<body>` HTML tag and immediately after add the following code:"

source_code :ruby, <<-RUBY
<% flash.each do |name, msg| %>
<div><%= msg %></div>
<% end %>
RUBY
end

step "Confirm your changes" do
message "Look at <http://localhost:3000>."
end
}


explanation {

message <<-MARKDOWN
* `format.html { redirect_to topics_path, notice: 'Topic was successfully created.' }`:
* `format.html` means that the server should send html back to the browser
* `redirect_to topics_path` means show the **topics list page** when we're done creating a topic
* `notice: 'Topic was successfully created.'` puts the message into the flash so it will be displayed on the topics list
MARKDOWN
}

next_step "credits_and_next_steps"
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
section "Overview" do
message <<-MARKDOWN

### What's a web server?

A web server listens for incoming requests from the browser and then asks to your application what it
would like to send back. This will usually be HTML in our case.

### Why run our app locally?

Running your app locally provides a very simple means to see your changes before you commit and push them to Heroku.

MARKDOWN
end

steps do
step do
console "rails server"
end
step do
text "Point your web browser to "
url "http://localhost:3000"
p "See your web app actually running!"
end

step do
message "When at the terminal with your running rails server, type Control+C to stop rails server. You can do this now."
result <<-STOPPING_RAILS_SERVER
^C[2012-03-31 08:33:11] INFO going to shutdown ...
[2012-03-31 08:33:11] INFO WEBrick::HTTPServer#start done.
Exiting
STOPPING_RAILS_SERVER
end

important <<-MARKDOWN
On Windows, sometimes Control-C doesn't work. In that case, look for the key called 'Break' or 'Pause' and press
Control-Break, then answer Y at the prompt. If there is no Pause/Break key on your keyboard, you can run `ruby script/rails server`
instead of `rails server` which should allow Control-C to stop the server.
MARKDOWN
end

next_step "creating_a_migration"
62 changes: 62 additions & 0 deletions sites/suggestotron-sans-scaffolds/start_using_git.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
section "Overview" do
message <<-MARKDOWN
### What is Git?
Git is a version control system (VCS) that allows us to track changes to our application over time.
By checking your application into git now, you're creating a record of your starting point.
Whenever you make a change during today's workshop, we'll add it to git before moving on.

### Why use it?
Most practically, it's what Heroku expects (Heroku is the service we'll be using to put our app online.)
But more than that, using Git means that if anything ever breaks, or you make a change you don't like, you can use git as an all-powerful "undo" technique.
But that only works when you remember to commit early and often!

### How does Git work?
When you make a Git repository and then commit your work to it, it takes a snapshot of your work and saves it.
Then, if you want to go back to that snapshot, you can! Git also does A LOT MORE, but we'll have to cover that another day.

### Does this have anything to do with GitHub?
GitHub is a service that allows people to collaborate, and it's very popular with open source projects.
But Git itself is simply the version control system that GitHub uses, so you can use Git totally separate from GitHub.

MARKDOWN
end

steps do

step do
console "git init"
message "Now you have a Git repository (or repo for short)."
end

step do
console "git status"

message "`git status` tells you everything git sees as modified, new, or missing."
message "The first time you run this, you should see a ton of stuff."
end

step do
console "git add ."
message "`git add .` tells git that you want to add the current directory (aka `.`) and everything under it to the repo."
tip do
message <<-MARKDOWN
With Git, there are usually many ways to do very similar things.

* `git add foo.txt` adds a file named `foo.txt`
* `git add .` adds all new files and changed files, but *keeps* files that you've deleted
* `git add -A` adds everything, including deletions

"Adding deletions" may sound weird, but if you think of a version control system as keeping track of *changes*, it might make more sense. Most people use `git add .` but `git add -A` can be safer. No matter what, `git status` is your friend.
MARKDOWN
end
end

step do
console "git commit -m \"Added all the things\""
message "`git commit` tells git to actually _do_ all things you've said you wanted to do."
message "This is done in two steps so you can group multiple changes together."
message "`-m \"Added all the things\"` is just a shortcut to say what your commit message is. You can skip that part and git will bring up an editor to fill out a more detailed message."
end
end

next_step "running_your_application_locally"
71 changes: 71 additions & 0 deletions sites/suggestotron-sans-scaffolds/suggestotron-sans-scaffolds.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
message <<-MARKDOWN
### Goal

The goal of this curriculum is to teach you how the various pieces of a Ruby on Rails
applications work together. You're going to create a voting system for you and your
friends to play with. You've decided at a minimum, you'd like to
allow users to:

* view the topics sorted by number of votes
* vote on topics
* create, edit, and destroy topics

You've sketched up an initial screenshot of what you want it to look like:

![screenshot](img/finished_app.png)

You may have built the same app before using Rails helpers like `rails generate scaffold`. None of that here! We're going to connect the models, views, and controllers together ourselves, and hopefully you'll have a better idea of how things fit together by the end of today.

### Requirements

We're going to be working with:

* ruby 1.9.3 installed via rvm (mac or linux) or RailsInstaller (mac or windows)
* rails 3.2.x or rails 4.0.x
* bundler
* sqlite
* the text editor of your choice

Everything should be set up the night before during our
installfest. Please ensure you have everything working _before_ you
show up for the workshop on Saturday.

You can verify that you have everything working by trying this out in your terminal:

<div class="console"><pre>
$ irb
>> 1 + 2
=> 3
>> require "active_support"
=> true
>> exit
$
</pre>
</div>

If you can do that, you are probably good to go.

### Working Effectively and Efficiently

We highly recommend you do the following:

* Bring up your terminal and open 2 tabs:
* One is for regular terminal stuffs
* One will be for irb (aka rails console). We'll explain later
* Open your browser fresh or hide any windows you already have open.
* Bring up one window with two tabs
* One for this content
* One for interacting with your app.
* Open your text editor and _do not ever close it_. We're not quitters.
* Hide all extra applications. Turn off twitter, IM, and all other distractions.

By minimizing the number of things you interact with, you reduce the
amount of time spent switching between them and the context lost as
you work through the lessons. Having 50 tabs open in your web
browser gets confusing and wastes time.
MARKDOWN

tip "The section above, about working effectively and efficiently, is a really, really good idea. if you didn't read it, you should totally stop and read it now."

next_step "getting_started"