main dbc9fe93f372 cached
86 files
454.4 KB
115.8k tokens
12 symbols
1 requests
Download .txt
Showing preview only (479K chars total). Download the full file or copy to clipboard to get everything.
Repository: railsgirls/guides.railsgirls.com
Branch: main
Commit: dbc9fe93f372
Files: 86
Total size: 454.4 KB

Directory structure:
gitextract_3vukf4_h/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── deploy.yml
├── .gitignore
├── .ruby-version
├── 404.html
├── Gemfile
├── LICENSE
├── README.md
├── _config.yml
├── _includes/
│   ├── analytics.html
│   ├── footer.html
│   ├── github-corner.html
│   ├── header.html
│   ├── main-guide-intro.html
│   └── main_guides.md
├── _layouts/
│   ├── default.html
│   ├── guide.md
│   └── main_guide.md
├── _pages/
│   ├── activeadmin.md
│   ├── app.md
│   ├── coach.md
│   ├── commenting.md
│   ├── continuous-codeship.md
│   ├── continuous-snap-ci.md
│   ├── continuous-travis.md
│   ├── contributing.md
│   ├── deployment/
│   │   ├── anynines.md
│   │   ├── digital-ocean.md
│   │   ├── engineyard.md
│   │   ├── fly-io.md
│   │   ├── heroku.md
│   │   └── openshift.md
│   ├── deployment.md
│   ├── design-using-html-and-css-chinese.md
│   ├── design.md
│   ├── devise.md
│   ├── diary-app.md
│   ├── github.md
│   ├── gravatar.md
│   ├── guide-to-the-guide.md
│   ├── guide.md
│   ├── how-to-continue-with-programming.md
│   ├── html-and-css.md
│   ├── install/
│   │   ├── linux.md
│   │   ├── macos.md
│   │   ├── replit.md
│   │   ├── virtual-machine.md
│   │   └── windows.md
│   ├── install.md
│   ├── new-homepage.md
│   ├── new-page.md
│   ├── passenger.md
│   ├── remote-pairing-for-the-win.md
│   ├── ruby-atm.md
│   ├── ruby-game.md
│   ├── ruby-intro.md
│   ├── shoulda-matchers.md
│   ├── simple-app.md
│   ├── sinatra-app-tutorial.md
│   ├── sinatra-html.md
│   ├── sinatra.md
│   ├── start.md
│   ├── test-driven-development.md
│   ├── testing-rspec.md
│   ├── thumbnails.md
│   ├── tools.md
│   ├── touristic-autism_basic-app.md
│   ├── touristic-autism_continuous-deployment.md
│   ├── touristic-autism_design.md
│   ├── touristic-autism_git.md
│   ├── touristic-autism_google-map.md
│   ├── touristic-autism_image-upload.md
│   ├── touristic-autism_intro.md
│   ├── touristic-autism_resource-modeling.md
│   ├── touristic-autism_resource-rating.md
│   ├── touristic-autism_static-pages-tdd.md
│   ├── twitter-widget.md
│   ├── uploads.md
│   └── videos.md
├── _plugins/
│   └── coach.rb
├── css/
│   ├── code.css
│   └── style.css
├── index.html
└── js/
    ├── guides.js
    ├── js.cookie.js
    └── mobile-menu.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: 'weekly'


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy site

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["main"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
      - name: Setup Ruby
        uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
        with:
          bundler-cache: true # runs 'bundle install' and caches installed gems automatically
          cache-version: 0 # Increment this number if you need to re-download cached gems
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5
      - name: Build with Jekyll
        # Outputs to the './_site' directory by default
        run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
        env:
          JEKYLL_ENV: production
      - name: Upload artifact
        # Automatically uploads an artifact from the './_site' directory by default
        uses: actions/upload-pages-artifact@v4

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .gitignore
================================================
.bundle/
_site/
.DS_Store
*.swp


================================================
FILE: .ruby-version
================================================
3.2.8


================================================
FILE: 404.html
================================================
---
layout: default
title: "Page not found"
permalink: /404.html
---

<div class="box text-center">
  <h1>Page not found</h1>

  <p>The page you are looking for does not exist.</p>
  <p>It may have moved, renamed or deleted.</p>

  <p>Please visit the <a href="/">guides homepage</a> for a list of all available guides.</p>
</div>


================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

gem "jekyll"
gem "jekyll-redirect-from"
gem "webrick"


================================================
FILE: LICENSE
================================================
Creative Commons Attribution-Share Alike 3.0 License.
https://creativecommons.org/licenses/by-sa/3.0


================================================
FILE: README.md
================================================
# Rails Girls Guides

<a href="https://railsgirls.com" target="_blank"><img alt="Rails Girls" src="/images/rails-girls-logo.png" width="15%" align="right"></a>

The purpose of Rails Girls is to give tools for women to understand technology. The Rails Girls events do this by providing a great first experience on building the Internet.

Rails Girls was founded at the end of 2010 in Helsinki. Originally intended as a one-time event, we never thought to see so many chapters from all around the world! This guide will help you get started.

You can use our materials and instructions to roll out your own workshop in your city, workplace or kitchen! Read more about Rails Girls at https://railsgirls.com

## Quick start

View the guides at https://guides.railsgirls.com or clone this repo and install & run [jekyll](https://github.com/mojombo/jekyll)

### Installing jekyll

```
$ cd guides.railsgirls.com
```

```
$ bundle install
```

### Pygments and Code Highlighting

The guides use the [pygments](https://pygments.org/) library to do syntax highlighting. If you don't have it installed you won't be able to see the highlight sections like the following:

```
{% highlight %}
{% endhighlight %}
```

If you aren't editing the code blocks, you can safely ignore this. If you want pygments, you can follow the [install instructions](https://jekyllrb.com/docs/installation/) in the "Pygments" section.

### Coach highlights

A custom Liquid tag is available for coach notes. Add these to guides when you want the coach to explain something. Use this tag to make sure the visual element is always the same and easy to recognize.

```
{% coach %}
Add helpful text here for the coach!
{% endcoach %}
```

### Run jekyll

```
$ bundle exec jekyll server --watch
```

### Styling

Wrap keyboard shortcuts with [kbd](https://www.w3.org/wiki/HTML/Elements/kbd) HTML tag.

To make posts consistent in style use `Ctrl+C` over `CTRL-c`/`ctrl+c`

```
To shut down the server you can hit <kbd>Ctrl</kbd>+<kbd>C</kbd>
```

### Having trouble?

You might find some useful hints in this jekyll issue if it's not working as expected: [Issue 503](https://github.com/mojombo/jekyll/issues/503)

## Contributing a Guide

To contribute a guide, view the instructions at https://guides.railsgirls.com/contributing

## X

For updates and more, follow [@railsgirls](https://twitter.com/railsgirls) on X

## Website & Blog

Official website and blog for Rails Girls movement can be found at https://railsgirls.com

## E-mail list

Global mailing list for Rails Girls events can be found at https://groups.google.com/group/rails-girls-team

## Credits

* Karri Saarinen / [@karrisaarinen](https://twitter.com/karrisaarinen) / [github](https://github.com/ksaa)
* Linda Liukas / [@lindaliukas](https://twitter.com/lindaliukas) / [github](https://github.com/lindaliukas)
* Vesa Vänskä / [@vesan](https://twitter.com/vesan) / [github](https://github.com/vesan)
* Terence Lee / [@hone02](https://twitter.com/hone02) / [github](https://github.com/hone)
* Tom de Bruijn / [@tombruijn](https://mastodon.social/@tombruijn) / [GitHub](https://github.com/tombruijn)

..and all the other coaches and people making Rails Girls awesome. Please add yourself!

## LICENSE
[![License: CC BY-SA 3.0](https://licensebuttons.net/l/by-sa/3.0/80x15.png)](https://creativecommons.org/licenses/by-sa/2.0/)


================================================
FILE: _config.yml
================================================
permalink: pretty
markdown: kramdown
include:
  - _pages
exclude:
  - ".rvmrc"
  - ".rbenv-version"
  - ".ruby-version"
  - "CNAME"
  - "Gemfile"
  - "Gemfile.lock"
  - "README.md"
  - "node_modules/"
  - "vendor/bundle/"
  - "vendor/cache/"
  - "vendor/gems/"
  - "vendor/ruby/"
url: https://guides.railsgirls.com
source_url: https://github.com/railsgirls/guides.railsgirls.com/blob/main/
plugins:
  - jekyll-redirect-from
site_title: "Rails Girls Guides"
default_page_description: "Learn how to make your own web apps with the Rails Girls guides."


================================================
FILE: _includes/analytics.html
================================================
<script type="text/javascript">
  //<![CDATA[
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-19631067-3']);
  _gaq.push(['_trackPageview']);

  (function () {
    var ga = document.createElement('script');
    ga.type = 'text/javascript';
    ga.async = true;
    ga.src =
      ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') +
      '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ga, s);
  })();
  //]]>
</script>


================================================
FILE: _includes/footer.html
================================================
<footer>
  <p>
    This work is licensed under a
    <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0 License</a>
  </p>
  <p>
    <a href="https://railsgirls.com">Rails Girls</a>
    &middot; Crafted with excitement from Helsinki, Finland &middot; Follow us on
    <a href="https://twitter.com/railsgirls">X</a>
    and
    <a href="https://www.facebook.com/railsgirls">Facebook</a>
  </p>
</footer>


================================================
FILE: _includes/github-corner.html
================================================
<a
    href="{{ site.source_url }}{{ page.path }}"
    class="github-corner"
    aria-label="Contribute to the guide on GitHub!"
  >
    <svg
      width="80"
      height="80"
      viewBox="0 0 250 250"
      style="
        fill: #fff;
        color: #d3360b;
        position: absolute;
        top: 0;
        border: 0;
        right: 0;
      "
      aria-hidden="true"
    >
      <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
      <path
        d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
        fill="currentColor"
        style="transform-origin: 130px 106px"
        class="octo-arm"
      ></path>
      <path
        d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
        fill="currentColor"
        class="octo-body"
      ></path>
    </svg>
  </a>


================================================
FILE: _includes/header.html
================================================
<header>
  {% include github-corner.html %}
  <div class="container">
    <div class="visible-desktop">
      <a class="span3" href="/" id="logo">
        <img alt="Rails Girls Guides" src="/images/railsgirls-guides.png" />
      </a>
      <nav class="nav pull-right">
        <a href="https://railsgirls.com/">Home</a>
        <a href="https://railsgirls.com/events.html">Events</a>
        <a href="https://railsgirls.tumblr.com/">Blog</a>
        <a href="/guide">Organizers</a>
        <a href="/">Guides</a>
      </nav>
    </div>

    <!-- Phone/Tablet -->
    <div class="visible-tablet visible-phone">
      <div class="nav navbar nav-pills">
        <a class="btn btn-link btn-navbar collapsed" onclick="toggleMobileMenu()">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </a>

        <a class="brand" href="/">Rails Girls Guides</a>

        <div class="nav-collapse navbar-responsive-collapse navbar-collapse" id='navbar-list' style='height: 0;'>
          <ul class="nav">
            <li><a href="https://railsgirls.com/">Home</a></li>
            <li><a href="https://railsgirls.com/events.html">Events</a></li>
            <li><a href="https://railsgirls.tumblr.com/">Blog</a></li>
            <li><a href="/guide">Organizers</a></li>
            <li><a href="/">Guides</a></li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</header>


================================================
FILE: _includes/main-guide-intro.html
================================================
<div class="guide-notice">
  This guide is a part of the <a href="/#guides">Rails Girls workshop main guides</a>. Make sure you follow the numbered guides in order before continuing.
</div>


================================================
FILE: _includes/main_guides.md
================================================
<hr>

If you're ever stuck during a guide, please ask your coach for help and also consult this [handy cheatsheet for Ruby, Rails, the console, the Text Editor etc](https://www.pragtob.info/rails-beginner-cheatsheet/).

## Guides

* Guide 1: [Start of the guide](/start) {% if page.permalink == 'start' %}(Current page!){% endif %}
* Guide 2: [Get to know the tools](/tools) {% if page.permalink == 'tools' %}(Current page!){% endif %}
* Guide 3: [Guide to install Rails](/install) {% if page.permalink == 'install' %}(Current page!){% endif %}
  - [Installation guide for macOS](/install/macos) {% if page.permalink == 'install/macos' %}(Current page!){% endif %}
  - [Installation guide for Windows](/install/windows) {% if page.permalink == 'install/windows' %}(Current page!){% endif %}
  - [Installation guide for Linux](/install/linux) {% if page.permalink == 'install/linux' %}(Current page!){% endif %}
  - [Installation guide for a Virtual Machine](/install/virtual-machine) {% if page.permalink == 'install/virtual-machine' %}(Current page!){% endif %}
  - [Installation guide for a Cloud service](/install/replit) {% if page.permalink == 'install/replit' %}(Current page!){% endif %}
* Guide 4: [Build Your First App](/app) {% if page.permalink == 'app' %}(Current page!){% endif %}
* Guide 5: [Style your app using HTML and CSS](/html-and-css) {% if page.permalink == 'html-and-css' %}(Current page!){% endif %}
* Guide 6: [Add a new page to your app](/new-page) {% if page.permalink == 'new-page' %}(Current page!){% endif %}
* Guide 7: [Add a new homepage to your app](/new-homepage) {% if page.permalink == 'new-homepage' %}(Current page!){% endif %}
* Guide 8: [Add picture uploads](/uploads) {% if page.permalink == 'uploads' %}(Current page!){% endif %}
* Guide 9: [Push Your App to GitHub](/github) {% if page.permalink == 'github' %}(Current page!){% endif %}
* Guide 10: [Put your app online](/deployment) {% if page.permalink == 'deployment' %}(Current page!){% endif %} with one of these services:
  - [Fly.io](/deployment/fly-io) {% if page.permalink == 'deployment/fly-io' %}(Current page!){% endif %}
  - [Heroku](/deployment/heroku) {% if page.permalink == 'deployment/heroku' %}(Current page!){% endif %}
  - [DigitalOcean](/deployment/digitalocean) {% if page.permalink == 'deployment/digitalocean' %}(Current page!){% endif %}
  - [OpenShift](/deployment/openshift) {% if page.permalink == 'deployment/openshift' %}(Current page!){% endif %}
  - [Anynines](/deployment/anynines) {% if page.permalink == 'deployment/anynines' %}(Current page!){% endif %}
  - [Engine Yard](/deployment/engineyard) {% if page.permalink == 'deployment/engineyard' %}(Current page!){% endif %}
* Guide 11: [Style the idea pages using HTML and CSS](/design) {% if page.permalink == 'design' %}(Current page!){% endif %}
* Guide 12: [Add comments to your app](/commenting) {% if page.permalink == 'commenting' %}(Current page!){% endif %}
* Guide 13: [Create picture thumbnails](/thumbnails) {% if page.permalink == 'thumbnails' %}(Current page!){% endif %}
* Guide 14: [Test your app with RSpec](/testing-rspec) {% if page.permalink == 'testing-rspec' %}(Current page!){% endif %}

[View all guides](/)


================================================
FILE: _layouts/default.html
================================================
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    {% capture page_title_capture %}
      {% if page.title == nil %}
        {{ site.site_title }}
      {% else %}
        {{ page.title }} - {{ site.site_title }}
      {% endif %}
    {% endcapture %}
    {% assign page_title = page_title_capture | strip %}

    {% capture page_description_capture %}
      {% if page.description == nil %}
        {{ site.default_page_description }}
      {% else %}
        {{ page.description }}
      {% endif %}
    {% endcapture %}
    {% assign page_description = page_description_capture | strip %}

    {% capture canonical_url %}{{ site.url }}/{{ page.permalink }}{% endcapture %}
    <title>{{ page_title }}</title>
    <link rel="canonical" href="{{ canonical_url }}">
    <!--[if lt IE 9]>
      <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <script src="/js/prefixfree.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" integrity="sha384-SDFvKZaD/OapoAVqhWJM8vThqq+NQWczamziIoxiMYVNrVeUUrf2zhbsFvuHOrAh" crossorigin="anonymous" type="text/javascript"></script>
    <script src="/js/js.cookie.js"></script>
    <script src="/js/guides.js"></script>
    <script src="/js/mobile-menu.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" integrity="sha384-j4yX2PowqrVy4Ogwr6u4kWzszBjcwPSvEjXy5oAODYFpI/KZCiVl8hRTGAJULguo" crossorigin="anonymous" rel="stylesheet">
    <link href="/css/code.css" rel="stylesheet" />
    <link href="/css/style.css" rel="stylesheet" />
    <link href="/favicon.png" rel="shortcut icon" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta property="og:site_name" content="{{ site.site_title }}">
    <meta property="og:title" content="{{ page_title }}">
    <meta name="og:description" content="{{ page_description }}">
    <meta property="og:type" content="website">
    <meta property="og:url" content="{{ canonical_url }}">
    <meta property="og:image" content="{{ site.url }}/images/rails-girls-sq.png">
    <meta property="og:image:width" content="300">
    <meta property="og:image:height" content="281">

    <meta name="twitter:site" content="@railsgirls">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="{{ page_title }}">
    <meta name="twitter:description" content="{{ page_description }}">
    <meta name="twitter:image" content="{{ site.url }}/images/rails-girls-sq.png">
    <meta name="twitter:url" content="{{ canonical_url }}">
  </head>
  <body>
    {% include header.html %}
    <main class="container">
      {{ content }}
    </main>

    <button onclick="topFunction()" class="go-to-top-arrow" title="Go to top"><div class="arrow"></div></button>
    {% include footer.html %}
    {% include analytics.html %}
  </body>
</html>


================================================
FILE: _layouts/guide.md
================================================
---
layout: default
---

<article class="guide">
{{ content }}
<hr>
Want to learn more? <a href="/">View more guides!</a>
</article>


================================================
FILE: _layouts/main_guide.md
================================================
---
layout: default
---

<article class="guide">
{{ content }}
{% capture guides %}
{% include main_guides.md %}
{% endcapture %}
{{ guides | markdownify }}
</article>


================================================
FILE: _pages/activeadmin.md
================================================
---
layout: guide
title: Adding a back-end with Active Admin
permalink: backend-with-active-admin
---

# Adding a back-end with Active Admin

*Created by [Rasmus Kjellberg](https://www.rasmuskjellberg.se)*

**This guide assumes that you have already built a Rails Girls app by** [**following the app development guide**](/app).

Active Admin is a Ruby on Rails plugin for generating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. You can read more about Active Admin [here](https://activeadmin.info/).

## Adding the "Active Admin" gem
Open up your `Gemfile` and add these lines

{% highlight ruby %}
gem 'devise'
gem 'activeadmin', github: 'activeadmin'
gem 'inherited_resources', github: 'activeadmin/inherited_resources'
{% endhighlight %}
and run
{% highlight sh %}
bundle install
{% endhighlight %}
to install the gems.

After updating your bundle, run the installer
{% highlight sh %}
rails generate active_admin:install
{% endhighlight %}

The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations.

Migrate your db and start the server:
{% highlight sh %}
rails db:migrate
rails server
{% endhighlight %}

## Creating your first admin account
Open up the Rails console and create your new user via the `AdminUser` model:
{% highlight sh %}
rails console
{% endhighlight %}

Once booted (the terminal shows `irb(main):001:0>`), you can run this command:
{% highlight sh %}
AdminUser.create(:email => 'admin@railsgirls.com', :password => 'password123', :password_confirmation => 'password123')
{% endhighlight %}

You should see something like:
{% highlight sh %}
# (0.3ms)  begin transaction
# SQL (0.4ms)  INSERT INTO "admin_users" ...
# (0.9ms)  commit transaction
{% endhighlight %}

You can exit the console session with a simple `exit` command:
{% highlight sh %}
irb(main):002:0> exit
{% endhighlight %}

## Accessing your admin panel
Visit <http://localhost:3000/admin> and log in using your created credentials.

Voila! You're on your brand new Active Admin dashboard.

## Add "Ideas" to back-end
To register your `Idea` model with Active Admin, run:
{% highlight sh %}
rails generate active_admin:resource Idea
{% endhighlight %}
Refresh your admin page and you will find [Ideas](http://localhost:3000/admin/ideas) in the navigation.

*You can replace "Idea" with whatever model you like to register another model with Active Admin.*

### Setting up Strong Parameters
To prevent **ActiveModel::ForbiddenAttributesError in Admin::IdeasController#update** exception when updating a model you have to use the [permit_params](https://activeadmin.info/2-resource-customization.html) method to define which attributes may be changed:

Open up your `app/admin/idea.rb` file and add `:name`, `:description` and `:picture` to `permit_params`:
{% highlight ruby %}
ActiveAdmin.register Idea do
  permit_params :name, :description, :picture
end
{% endhighlight %}

## Remove "new", "edit" and "destroy" for users.
If you don't want your non-admin users to update your ideas you can easy fix this by updating your route file to only allow "index" and "show". Add `only: [:show, :index]` to `config/route.rb`:
{% highlight ruby %}
resources :ideas, only: [:show, :index]
{% endhighlight %}

**Don't forget to remove now broken links from your front-end code such as:** `<%= link_to 'New Idea', new_idea_path %>`, `<%= link_to 'Edit', edit_idea_path(idea) %>`, `<%= link_to 'Destroy', idea, method: :delete, data: { confirm: 'Are you sure?' } %>`

Voila! You can now manage your Ideas from your new admin panel!

## What next?

* Add another resource to admin such as Blog and Comments


================================================
FILE: _pages/app.md
================================================
---
layout: main_guide
title: Build your first app
description: "Start building your first Ruby on Rails app with Rails generators."
permalink: app
---

# Build your first app

*Originally created by Vesa Vänskä, [@vesan](https://twitter.com/vesan)*

{% include main-guide-intro.html %}

Welcome to the workshop! This is the guide you'll be starting with on the day of the workshop. Did you have trouble getting the installation to work? Ask your coach for help first.

## Help from the coach

When you see the box below, ask your coach to read it and help out where necessary.

{% coach %}
Hi coach 👋 Thank you so much for helping out today!
{% endcoach %}

## Learn about Ruby

In these next couple guides you're going to create a new app. For this you'll be using the Ruby on Rails framework. The Rails framework is written in the Ruby programming language. To get a better idea of how Ruby works, read the [Rails Girls guide to Ruby](/ruby-intro) if you haven't ever written any Ruby, or go to the slightly more advanced [try.ruby-lang.org](https://try.ruby-lang.org/) course before you continue.

## Creating the application

In this guide you're going to create a new app. For this you'll be using the Ruby on Rails framework. The app itself will be called *railsgirls*.

First, open the Terminal app and type in these commands:

<div class="os-specific">
  <div class="mac nix">
{% highlight sh %}
mkdir projects
{% endhighlight %}

    <div>
<p>You can verify that a directory named <code>projects</code> was created by running the list command: <code>ls</code>. You should see the <code>projects</code> directory in the output. Now you want to change the directory you are currently in to the <code>projects</code> folder by running:</p>
    </div>

{% highlight sh %}
cd projects
{% endhighlight %}

    <div>
<p>You can verify you are now in an empty directory or folder by again running the <code>ls</code> command. Now you want to create a new app called <code>railsgirls</code> by running:</p>
    </div>

{% highlight sh %}
rails new railsgirls
{% endhighlight %}

    <div>
<p>This will create a new app in the folder <code>railsgirls</code>, so we again want to change the directory to be inside of our Rails app by running:</p>
    </div>

{% highlight sh %}
cd railsgirls
{% endhighlight %}

    <div>
<p>If you run <code>ls</code> inside of the directory you should see folders such as <code>app</code> and <code>config</code>. You can then start the Rails server by running:</p>
    </div>

{% highlight sh %}
rails server
{% endhighlight %}
  </div>

  <div class="win">
{% highlight sh %}
mkdir projects
{% endhighlight %}

    <div>
<p>You can verify that a directory named <code>projects</code> was created by running the list command: <code>dir</code>. You should see the <code>projects</code> directory in the output. Now you want to change the directory you are currently in to the <code>projects</code> folder by running:</p>
    </div>

{% highlight sh %}
cd projects
{% endhighlight %}

    <div>
<p>You can verify you are now in an empty directory or folder by again running the <code>dir</code> command. Now you want to create a new app called <code>railsgirls</code> by running:</p>
    </div>

{% highlight sh %}
rails new railsgirls
{% endhighlight %}

    <div>
<p>This will create a new app in the folder <code>railsgirls</code>, so we again want to change the directory to be inside of our Rails app by running:</p>
    </div>

{% highlight sh %}
cd railsgirls
{% endhighlight %}

    <div>
<p>If you run <code>dir</code> inside of the directory you should see folders such as <code>app</code> and <code>config</code>. You can then start the Rails server by running:</p>
    </div>

{% highlight sh %}
rails server
{% endhighlight %}
  </div>
</div>

Open <http://localhost:3000> in your Browser. Clicking the link should open it in a new tab and show the `localhost:3000` in the address bar. If you are using a cloud service (e.g. Replit), use its preview functionality instead (see [installation guide](/install/replit) for details).

You should see a page with the Rails logo, which means that your Rails app is up and running. The `rails new` generator created a lot of app code for you to get started and we'll be modifying it in the rest of this workshop.

Notice in the Terminal window the command prompt is not visible because it is now running the Rails server. The command prompt will look something like this, but it may be different on your laptop:

<div class="os-specific">
  <div class="mac nix">
{% highlight sh %}
$
{% endhighlight %}
  </div>
  <div class="win">
{% highlight sh %}
>
{% endhighlight %}
  </div>
</div>

When the command prompt is not visible you cannot execute new commands. If you try running `cd` or another command it will not work. To stop the Rails server and return to the normal command prompt in the same Terminal window, press <kbd>Ctrl</kbd>+<kbd>C</kbd> in the Terminal to quit the Rails server.

{% coach %}
- Make sure it's clear what each command does: `cd`, `dir`/`ls`, `mkdir`.
- Briefly explain what was generated by `rails new`.
- Briefly explain what the `rails server` command does and why we need it.
- Briefly explain how can you stop the server.

Resources: Guide to the Guide [creating the application](https://guides.railsgirls.com/guide-to-the-guide#1_create_the_application), Rails Guides [rails new](https://guides.rubyonrails.org/getting_started.html#creating-the-blog-application)

{% endcoach %}

## Create Idea scaffold

You now have your own app, but it doesn't do anything yet. It only shows the Rails logo.

Next you're going to use Rails' scaffold functionality to generate a starting point that allows you to list, add, remove, edit, and view things; in your case _ideas_.

Run the following command in the Terminal app:

{% highlight sh %}
rails generate scaffold idea name:string description:text picture:string
{% endhighlight %}

{% coach %}
- Explain what Rails scaffolding is. How does it help us create parts of an app quickly?
- Briefly explain the `rails generate scaffold` command and how it works. What do they arguments mean?
    - What is the model name argument?
    - How do you specify database fields with `name:string` and what do they parts mean?

Resource: Guide to the guide [scaffolding](https://guides.railsgirls.com/guide-to-the-guide#2_create_idea_scaffold)
{% endcoach %}

The scaffold creates new files in your project directory, but to get it to work properly we need to run a couple of other commands to update our database and restart the server.

{% highlight sh %}
rails db:migrate
rails server
{% endhighlight %}

{% coach %}
What are database migrations and why do you need them?

Resource: Guide to the guide [scaffolding](https://guides.railsgirls.com/guide-to-the-guide#2_create_idea_scaffold) or Rails Beginner [rails commands](https://www.pragtob.info/rails-beginner-cheatsheet#rails-commands)
{% endcoach %}

Open <http://localhost:3000/ideas> in your Browser. Cloud service (e.g. Replit) users need to append `/ideas` to their preview URL instead (see [installation guide](/install/replit)).

Click around and test what you got by running these few command-line commands. You should be able to make new ideas, view, edit and delete (destroy) them.

## Finetune the routes

Open <http://localhost:3000> (or your preview URL). It will show a page with only the Rails logo. Let's make it redirect to the ideas page instead.

Open the `config/routes.rb` file in your Text Editor. After the first line, add this line and save it:

{% highlight ruby %}
root to: redirect("/ideas")
{% endhighlight %}

Test the change by opening the root path (that is, <http://localhost:3000/> or your preview URL) in your Browser. It should now open the ideas index page when you visit the root path. The label in the Browser's address bar should have automatically changed to <http://localhost:3000/ideas>.

## Next steps

You have now created your first app! Congratulations!

From here we will continuing working on the app to improve the design with HTML and CSS, add more pages, add picture uploads, put your app online so that others can see it as well, share the code with others, allow people to leave comments, etc.

Talk with your coach about the steps you took in this guide. Do you have questions about any of the steps? Ask them before moving on to the next guide.


================================================
FILE: _pages/coach.md
================================================
---
layout: guide
title: Guides
descriptive: "The guide for coaches to prepare their participation in a Rails Girls workshop."
permalink: coach
---

# Being a Rails Girls coach

*All your basic questions answered in one place*

### What do I need to be a Rails Girls coach?

So, you've heard about [Rails Girls](https://railsgirls.com) and are wondering if you've got what it takes to be a coach at one of the workshops? That's awesome! Your interest in helping beginners dip their toes into web programming is already a great prerequisite! What else do you need?

- Patience, willingness to help, and a friendly attitude :)
- Being able to answer all sorts of questions in a beginner friendly way (even if the explanation isn't *technically* completely exact) throughout the duration of the workshop.
- Experience with web programming (you know what MVC means, right?), not necessarily in Rails.
- Some time to go through the [basic app tutorial][app] before the event.

### Why should I be a Rails Girls coach?

You mean besides incredibly good karma? Here are some very likely outcomes:

- You'll meet interesting new people outside your usual developer group.
- You'll probably learn something new by answering questions you never thought of asking yourself.
- Eternal gratitude from your group of girls and the Rails Girls community.
- An epic #FridayHug like you've never seen before.
- You'll help break down stereotypes about women not being interested in technology and programming and thus help your sisters, female friends and relatives, (future) daughters have more choices in their future. And you can add all that on your CV!

### Choice of technology
Rails Girls workshops give the first experience in software craftsmanship through introducing the participants to Ruby, Rails and HTML/CSS. The curriculum has been built around these technologies. If the workshop is too difficult or deep, it will not encourage the beginners to continue as it's perceived too hard. Rails Girls workshops are not about learning programming fast and efficiently. It's about the open environment, excitement and getting to know the tools they can use, and having a great day learning about programming, the community, web apps and more. We would love to see other additions to e.g. follow up meetups. If you'd like to host a beginner-friendly, welcome event for women in other technologies or frameworks, we strongly encourage you to do so and use the existing materials. All Rails Girls content is licensed under creative commons.


### Time to complete app
There's loads of time to complete the app, and so it is more important to slowly explain what is happening in each step, as it is a lot of copy pasting and if attendees rush through the guide, they will be done soon but not understand at all what happened.
<br> There's a LOT (4-5) h reserved for the app, tweaking it and putting it online for others to see so there is no hurry :)


### Swag
Believe it or not, for most, it is really important. It makes the environment different. You decide how, but little crafts (making buttons), stickers, cupcakes, balloons, posters, or anything you can come up with makes all the difference.


### Inclusivity
Rails Girls is an inclusive, safe and welcoming experience to everyone. The workshops are primarily intended for beginner women and crafted for this specific user group, but we've always been open to including other skill-levels and genders. Rails Girls coaches are male and female. The end goal of Rails Girls is to enrich the entire Rails community by encouraging more diverse people to join it. If you want to make a different curriculum or group, all the material is online and you are welcome to use it under another name and brand.



### What if I've never done anything in Rails?

Why haven't you yet? Just kidding. That's not a problem at all, we've had a lot of coaches just like you and they were *super awesome*. As long as you're comfortable with any other similar framework, you'll be fine. Take a look at the [basic app guide][app] and you'll probably be able to figure out what's going on pretty soon. Pay attention to the "**Coach**" bits that tell you what you should be able to explain.

Usually there'll be at least somebody at the event who works with Rails on a regular basis, so don't be afraid to ask for help when bundle installs go all weird on you. Also, if you come across something unusual, just Google it with your group! It's ok to admit that you don't know everything and show the girls how you use Google to solve your everyday programming dilemmas.

### What exactly will I be doing as a coach?

The structure of workshop varies a bit from city to city, so your local organizer group will be able to guide you through the details. Usually there's a pre-event meeting or dinner with coaches where you can ask all you questions.

### Answering questions
Often coaches who are just one step ahead of attendees are the best at explaining :) Use real life metaphors and explain very high-level. Explaining too deep will cause a flood of information that is not necessary at the beginning.

#### Installation Party

Generally speaking, the Rails Girls workshops begin with an Installation party during which you'll be asked to help girls [install the required software][install] (Rails and a text editor). You don't have to be an expert on all operating systems, but you can help on those you are familiar with.

#### Helping girls build their first app

During the following day, you will be the star of the show and help your group of anywhere from 2 to 5 girls build their first [web app][app] in Rails with the help of the tutorial. Usually that happens just after the initial batch of lectures sometime after 11 AM (aka they'll serve you coffee first).

Going through the tutorial on your own at home will usually be all the preparation you need. The girls will have the app guide open on their screens, so just guide them through the process, providing explanations of what's going on at each step. The explanations shouldn't be highly technical; try to simplify the answer by providing easy to remember metaphors. And remember that there is no such thing as a stupid question at a Rails Girls workshop! Let girls know they can ask you about anything along the way; you can spend more time on parts they find more interesting.

Also, don't be discouraged if you'll sometimes need to try a few different explanations. Most girls will be beginners, so they won't have many existing points of reference (bonus point: nor will they have any bad habits some programmers tend to pick up along the way). If you get to the end of the basic app tutorial, you can explore additional guides at the end or work on whatever your group is most interested in; design is usually a popular choice, but some girls will want to try building another app. You can also prepare your own challenges for girls or explore helpful resources (documentation etc).

If you need help with anything, don't be afraid to use Google or ask another coach to help you out. And don't be afraid to ask for a break if you need it, it's going to be a long day, but we can promise you'll get home with a big smile and a warm heart :)

* Check Lucy Bain's additional [teaching notes to the app](https://github.com/lbain/railsgirls)

### Are you in?

Good, we're happy to have you on board! Get in touch with organizers of your local event (if you aren't already) and they'll answer all the other questions you might have. You can usually find their contact info on the event's page.

If you're traveling abroad at the time of a Rails Girls workshop, do feel free to contact the organizers of the city you'll be visiting; we're always happy to welcome additional coaches! Not to mention that a Rails Girls workshop is a great excuse to visit a new city ;)

Some other great first-hand tips from Rails Girls coaches:

- [4 lessons learned from teaching at Rails Girls Berlin](https://pragtob.wordpress.com/2012/08/14/4-lessons-learned-from-teaching-at-rails-girls-berlin/)
- [I infiltrated #railsgirlslj, here’s what it was like](https://swizec.com/blog/i-infiltrated-railsgirlsj-heres-what-it-was-like/swizec/5717)
- [8 ways to enable workshop attendees to keep learning](https://pragtob.wordpress.com/2013/06/14/8-ways-to-enable-workshop-attendees-to-keep-learning/)
- [What I learned learning Rails / becoming a better teacher](https://floordrees.tumblr.com/post/58784746482/what-i-learned-learning-rails-becoming-a-better)
- [Tips for coaching a programming study group](https://coaching.rubymonstas.org/)

[app]: /app
[install]: /install



================================================
FILE: _pages/commenting.md
================================================
---
layout: main_guide
title: Add commenting functionality to your app
description: "Allow other people to leave comments on your ideas by adding a commenting feature to your Rails app."
permalink: commenting
---

# Add comments to your app

{% include main-guide-intro.html %}

We are going to add the possibility to comment on ideas in your *railsgirls* application. Comments are short messages that people can leave on websites. In this guide we'll be relying less on the Rails generators to create scaffolding. We'll be writing more Ruby code to implement this feature.

## Add comment routes

We'll start by creating a new route for the comments. This will be nested under the ideas routes, so we can derive which idea the comment belongs to from the route.

Open the `config/routes.rb` file. Change the following line:

{% highlight ruby %}
resources :ideas
{% endhighlight %}

to these lines:

{% highlight ruby %}
resources :ideas do
  resources :comments
end
{% endhighlight %}

## Create comment model

Next up, creating a comment model, like we did with the ideas before, but without the controller and a bunch of other things. In this guide we'll be making more changes ourselves, rather than relying on generated code.

The command below will create a Comment model with a name, message body and with a reference to the ideas table. The latter will make it possible to leave comments on a specific idea, so they won't show on other idea pages.

{% highlight sh %}
rails generate model comment user_name:string body:text idea:references
{% endhighlight %}

A migration file has also been created. It lets your database know about the new comments table. Run the migrations using this command:

{% highlight sh %}
rails db:migrate
{% endhighlight %}

## Add relations to models

Your app needs to know about the relation between the two objects, ideas and comments, so you can fetch only the comments that belong to a specific idea. One idea can have many comments, but a comment can only belong to one idea.

Open `app/models/idea.rb` and below the line:

{% highlight ruby %}
class Idea < ApplicationRecord
{% endhighlight %}

add this line to tell it there can be many comments attached to the Idea model:

{% highlight ruby %}
has_many :comments
{% endhighlight %}

The comment also has to know that it belongs to an idea. Open the `app/models/comment.rb` file. You'll find the following contents:

{% highlight ruby %}
class Comment < ApplicationRecord
  belongs_to :idea
end
{% endhighlight %}

The comment already knows it "belongs to" an idea because of the line `belongs_to :idea`, which references back to the `Idea` model. This was automatically added by the migration we made earlier.

## Loading comments from the database

In `app/controllers/ideas_controller.rb` find the line that says `def show`. This is what we call a Ruby method, and it is responsible for loading things from the database to be used in the views (files with HTML we've edited before).

Change the `show` method so that it looks like this:

{% highlight ruby %}
def show
  @comments = @idea.comments
end
{% endhighlight %}

This will load the comments that belong a specific idea object from the database. We can then access the comments using the `@comments` instance variable in the view later.

## Making a comments controller

To store comments in the database, and remove them again later, we'll need a Rails controller. Like the IdeasController, this controller will perform databases queries, but for comments instead.

Create a file in the `app/controllers/` directory named `comments_controller.rb`.

<div class="os-specific">
  <div class="mac nix">
{% highlight sh %}
touch app/controllers/comments_controller.rb
{% endhighlight %}
  </div>
  <div class="win">
{% highlight sh %}
ni app/controllers/comments_controller.rb
{% endhighlight %}
  </div>
</div>

Open the file you just created in your Text Editor, it should be empty, and copy-paste in this code:

{% highlight ruby %}
class CommentsController < ApplicationController
  before_action :set_idea, only: %i[create destroy]
  before_action :set_comment, only: %i[destroy]

  def create
    @comment = @idea.comments.new(comment_params)

    if @comment.save
      redirect_to idea_path(@idea), notice: "Comment was successfully created."
    else
      render :new, status: :unprocessable_entity
    end
  end

  def destroy
    @comment.destroy

    redirect_to idea_path(@idea), notice: "Comment was successfully destroyed."
  end

  private

  def set_idea
    @idea = Idea.find(params[:idea_id])
  end

  def set_comment
    @comment = @idea.comments.find(params[:id])
  end

  def comment_params
    params.require(:comment).permit(:user_name, :body)
  end
end
{% endhighlight %}

This controller will listen to requests to create and delete (destroy) comments. When it receives such a request, it will tell the database what to store or remove, and redirect you back to the page you came from. But first, let's make the pages that will talk to this controller.

{% coach %}
Explain how controllers work and interact with HTTP requests, models and views.
{% endcoach %}

## Display the comments

We can use the relationship between ideas and comments to fetch them from the database and show them in your app.

Open `app/views/ideas/show.html.erb` and at the very bottom add these lines:

{% highlight erb %}
<h2>Comments</h2>
<% if @comments.any? %>
  <% @comments.each do |comment| %>
    <div>
      <p><strong><%= comment.user_name %></strong></p>
      <p><%= comment.body %></p>
      <%= button_to "Destroy this comment", idea_comment_path(@idea, comment), method: :delete, class: "btn btn-danger", form: { data: { turbo_confirm: "Are you sure?" } } %>
    </div>
  <% end %>
<% else %>
  <p>No comments found.</p>
<% end %>

<h2>Add a new comment</h2>
<%= render partial: "comments/form", locals: { idea: @idea } %>
{% endhighlight %}

This code will show the comments, but first we'll need a way to create comments. For that the last two lines render a comment submission form, which we'll create next.

## Create the comment form

To submit the form, we need to create a file with the form, so that it can be displayed.

Create a new directory in the `app/views/` directory named `comments/`.
Then, in that new directory, create a new file called `_form.html.erb`.

<div class="os-specific">
  <div class="mac nix">
{% highlight sh %}
mkdir -p app/views/comments/
touch app/views/comments/_form.html.erb
{% endhighlight %}
  </div>
  <div class="win">
{% highlight sh %}
md app/views/comments/
ni app/views/comments/_form.html.erb
{% endhighlight %}
  </div>
</div>

In this new file copy-paste these lines:

{% highlight erb %}
<%= form_with(model: [idea, idea.comments.build]) do |form| %>
  <div class="mb-3">
    <%= form.label :user_name, "Your name", class: "form-label" %>
    <%= form.text_field :user_name, class: "form-control" %>
  </div>

  <div class="mb-3">
    <%= form.label :body, "Comment message", class: "form-label" %>
    <%= form.text_area :body, class: "form-control" %>
  </div>

  <%= form.submit class: "btn btn-primary" %>
<% end %>
{% endhighlight %}

When you refresh your browser, the idea detail page should now have a form for adding a comment. Fill in your name and add a message. Then click the "Create comment" button. It should now say "Comment was successfully created." at the top of the page in green.

Congratulations! Your app now supports comments. We've added a new models for comments, named `Comment`, which talks to the database to store these comments. A new `CommentsController` controller that tells the model what to do, creating or deleting comments. The views are updated to show the comments per idea, create new comments with the form and delete them again with the delete buttons.

If you're interested, check out the detail page of a different idea. If all goes well, you should not be seeing the same comments on that idea detail page as the other one.


================================================
FILE: _pages/continuous-codeship.md
================================================
---
layout: guide
title: Continuous Deployment - cuz less hassle
permalink: continuous
---

# Continuous Deployment with the Codeship

*Created by Floor Drees, [@floordrees](https://twitter.com/floordrees)*

*Updated by Ely Flores, [@mignonnesaurus](https://twitter.com/mignonnesaurus)*

### What is this Continuous Deployment thing?

Continuous deployment is part of the continuous delivery 'movement'. The idea behind continuous delivery is to automate the software delivery process as far as possible. 

With a working continuous deployment chain in place you'll enforce Git deployments (everything must be committed to be tested and everything must be tested to be deployed), making collaboration easier and deployment faster. So you can focus on making your app even more awesome!

There are a few great companies sailing the continuous wave, in this guide we'll set up continuous deployment for our Ruby on Rails app from GitHub to Heroku, using the [Codeship](https://www.codeship.io). 

{% coach %}
Talk about the benefits of continuous deployment.
{% endcoach %}

### Sign up for Codeship

First, you need [a Codeship account](https://www.codeship.io/). Sign in to the Codeship with GitHub. The Codeship needs access to your GitHub repositories to be able to set them up, so make sure you allow access.  

Back at the Codeship, let’s create your first project. The first step is to select GitHub as your repository provider. In the list of your GitHub repositories, search for the repository you want to set up and select it. In our case, that's the one called something like “railsgirls”.

Now your repository is connected and you can set up your test commands. We've created a Ruby on Rails application. So choose “Ruby on Rails” as the framework used. This configures the setup commands and the test commands for you. By deleting the hash key (`#`) you can uncomment test commands you want to use for your application. For now you probably don't have tests set up yet, so you can skip this step and get back to it later.

Now let's finish your setup and go to the dashboard. You can trigger a so-called 'new build' for your application by changing something and then pushing to your repository: 
{% highlight sh %}
git add .
git commit -m "test Codeship integration"
git push origin master
{% endhighlight %}

You can access the build details by clicking the arrow on the right. Here you can follow the build while it's still running. Better than reality tv - promised. 

... and a few seconds later your build succeeded! You see all the commands that were run. After a few initial preparation commands the Codeship ran the commands that you specified a few moments ago. You can inspect the output of a single command by clicking on it. 

You've already pushed to your repository, watched your build log and got a green build. So you can finish the assistant at the top by clicking on the "click to finish" button.

### Setup Continuous Deployment

Now let's deploy your application to Heroku. Go to your project settings by clicking on the settings icon in the projects dropdown on the Codeship. Then navigate to the "Deployment" section. As you want to deploy to Heroku, click on the "Heroku" button.

You are asked to enter the name of your Heroku application and your API key. I sure hope you wrote that down somewhere! Enter your application's name and API key (to retrieve your Heroku API key, go to your Heroku account and click "Show API key") and save your deployment configuration.

From now on the Codeship will deploy your application to Heroku, every time you push to your GitHub repository. Neat!

### Give it a try
Now let's push a change and see if it gets deployed. Change something in your application first, then commit and push the change.

{% highlight sh %}
git add .
git commit -m "this changes everything"
git push
{% endhighlight %}

And immediately another build will start running on the Codeship. Go back to your project overview and you'll see the commands we already know from your first build. Plus: your application gets deployed to Heroku now and should be online after a minute or two.

#### Notes
If the "build fails" and you see an error like the following when pushing to heroku:
{% highlight sh %}
Warning: Permanently added 'heroku.com,<some-ip>' (RSA) to the list of known hosts.
 !  Your account funalinot@someemail.com does not have access to app-name.
 !
 !  SSH Key Fingerprint: <some-ssh-key-fingerprint>
 fatal: Could not read from remote repository.

 Please make sure you have the correct access rights
 and the repository exists.
{% endhighlight %}

This means that the codeship SSH key needs to be added to heroku as well.
To fix this issue:
> 1. In Codeship, get your `SSH public key` from your project -> _General_ Tab.
> 2. Go to your [Heroku account settings](https://dashboard.heroku.com/account)
> 3. Go to the _SSH Keys_ section
> 4. Click on _Add SSH Key_
> 5. Enter the `SSH public key` from step 1.
> 6. To make sure this works, go back to Codeship. In the build that failed, click on the arrow next to the _Failed_ button and then click _Restart Build_.
> 7. Celebrate when you see the Green _Success_ button meaning that the _Build Passed_ !


================================================
FILE: _pages/continuous-snap-ci.md
================================================
---
layout: guide
title: Continuous Deployment - cuz less hassle
permalink: continuous-snap-ci
---

# Continuous Deployment with the Snap CI

*Created by Akshay Karle, [@akshay_karle](https://twitter.com/akshay_karle)*

### What is this Continuous Deployment thing?

Continuous deployment is part of the continuous delivery 'movement'. The idea behind continuous delivery is to automate the software delivery process as far as possible.

With a working continuous deployment chain in place you'll enforce Git deployments (everything must be committed to be tested and everything must be tested to be deployed), making collaboration easier and deployment faster. So you can focus on making your app even more awesome!

There are a few great companies sailing the continuous wave, in this guide we'll set up continuous deployment for our Ruby on Rails app from GitHub to Heroku, using the [Snap CI](https://snap-ci.com).

{% coach %}
Talk about the benefits of continuous deployment.
{% endcoach %}

### Sign up for Snap CI

First, you need [a Snap CI account](https://snap-ci.com/). Sign in to the Snap CI with GitHub. Snap CI needs access to your GitHub repositories to be able to set them up, so make sure you allow access.

Back at the Snap CI, let’s create your first pipeline. The first step is to select GitHub as your repository provider. In the list of your GitHub repositories, search for the repository you want to set up and select it. In our case, that's the one called something like “railsgirls”.

Once you select the repository you wish to build, Snap CI will perform detections on your repository and makes a best attempt to automatically setup your [deployment pipeline](https://martinfowler.com/bliki/DeploymentPipeline.html) for you which will allow you to run your tests and deployments.

After a few seconds, Snap CI will automatically start building your repository, at this point you can click through the stages setup by Snap to see what they commands they run.

Sometimes, however, Snap CI may not be able to detect the right commands to build and test your repository. In such cases you can edit your pipeline configuration by visiting the Configuration page from the Builds page of your newly created pipeline and clicking 'Edit' to edit the pipeline. Now you can add or edit an existing stage which will build and run all the tests for your application.

If you feel unsure what stages you should be adding, you can have a look at the different Build recipes provided under the Ruby sub-category when adding a stage to figure out what commands should be run to correctly build and test your application. You can also take a look at the [getting started guide](https://docs.snap-ci.com/getting-started/) in the Snap CI documentation.

Once you've finished editing your pipeline configuration click 'Save'. This will save your configuration and automatically trigger a new build. You should now have a green build if all your tests pass of course :)

In case you have any test failures however, you can fix those and push the changes to GitHub:

{% highlight sh %}
git add .
git commit -m "fix tests"
git push origin master
{% endhighlight %}

Snap CI will automatically detect the changes from GitHub and run a new instance of the pipeline. At this point you've already started testing your code.

### Setup Continuous Deployment

The next step is to deploy your application. There are various platforms to deploy to, for now, let's look at how you can deploy to [Heroku](https://www.heroku.com/) as it is the easiest.

Go to your pipeline configuration edit page again and add a new Stage. This time Select the 'Deploy' category from the recipes on the left. The select 'Basic' recipe in the Heroku sub-category.

Enter a stage name of your choice (eg: deploy, go-live, etc.), keep the trigger automatic and then click 'Run as' dropdown to Sign into Heroku. Perform the sign in and authorise Snap CI. You should automatically comeback to Snap CI after the authorization. You can now select the Heroku application where you wish to deploy or create a new application from Snap CI itself. Check the 'Perform DB migrate' checkbox and save your configuration.

This should trigger another new build in Snap CI, but this time it runs the stage you just created which deploys to Heroku. Once the pipeline goes green, visit the Heroku application page where you deployed from Snap CI and your rails application should be online in a few minutes.

From here on, any new changes you make and push to your GitHub will be tested and deployed automatically by Snap CI.


================================================
FILE: _pages/continuous-travis.md
================================================
---
layout: guide
title: Continuous Deployment - cuz less hassle
permalink: continuous-travis
---

# Continuous Deployment with Travis

*Created by Floor Drees, [@floordrees](https://twitter.com/floordrees)*

### What is this Continuous Deployment thing?

Continuous deployment is part of the continuous delivery 'movement'. The idea behind continuous delivery is to automate the software delivery process as far as possible.

With a working continuous deployment chain in place you'll enforce Git deployments (everything must be committed to be tested and everything must be tested to be deployed), making collaboration easier and deployment faster. So you can focus on making your app even more awesome!

There are a few great companies sailing the continuous wave, in this guide we'll set up continuous deployment for our Ruby on Rails app from GitHub to anynines, using [Travis-ci](http://about.travis-ci.org/).

{% coach %}
Talk about the benefits of continuous deployment.
{% endcoach %}

### Github, Travis CI and anynines

The first thing we need is an app in a Github repository. And we have just that! Next you'll need to make sure you followed the guide on how to deploy your app via anynines until the very last step.

Then, we need to create a file called `manifest.yml` in the main directory of your app, so we can save some information about the deployment there. In your terminal run:

{% highlight sh %}
cf push
{% endhighlight %}

This will trigger a first deployment to anynines. The cf gem will notice that there is no `manifest.yml` and will ask you a standard set of configuration questions such as the desired number and memory size of your app instances, whether and which services to bind to them and most importantly, whether you want to store this information.
Please answer this question with a 'hell yes' as it will create the desired `manifest.yml` file!

Once your push was successful, you should be able to access your application using a browser of your choice, which means your are ready to setup Travis!

For now we don't have 'real tests', so we will go ahead and create a Travis configuration file that will fake a succeeding test suite. Please go to your local app directory and create a ``.travis.yml`` file. At the moment, paste the following content. We’ll add some more information later on, using the Travis gem.

{% highlight sh %}
language: ruby
script: 'true'
{% endhighlight %}

Your app now contains the Travis configuration but how should Travis know when to pull your code from Github and trigger test execution? This is where Github hooks come into play!

#### Travis CI Github hook activation

Commit and push a code change to your repository and check travis-ci.org to see if your test suite is being executed. You should also receive an email that your build succeeded.

{% highlight sh %}
git add .
git commit -m "test Travis integration"
git push origin master
{% endhighlight %}

Now we can configure the actual deployment.
Let's use the travis gem:
{% highlight sh %}
gem install travis
{% endhighlight %}

Now use the `travis` command to setup the anynines deployment.
{% highlight sh %}
travis setup cloudfoundry
{% endhighlight %}

In case you don’t know the anynines target URL use
{% highlight sh %}
cf target
{% endhighlight %}

to gather all information required for Travis setup. This includes target url, username, the organization and space you are currently using. You can also take a look-see at the welcome mail you have received after signing up at anynines.com.

After the `travis` command has finished, your ``.travis.yml`` should look somewhat like this:
{% highlight sh %}
language: ruby
script: 'true'
deploy:
  provider: cloudfoundry
  target: https://api.de.a9s.eu
  username: jane.doe@example.com
  password:
    secure: your encryped password determined by the travis gem=
  organization: railsgirls
  space: heaven
  on:
    repo: jane/railsgirls
{% endhighlight %}

Don’t forget to commit and push your changes to ``.travis.yml`` as it will be required in your Github repository to take effect.

From now on whenever you commit changes to your Github repository, tests will be run and your app is being deployed. Travis will then show a log output similar to this:

{% highlight sh %}
Installing deploy dependencies
Fetching: addressable-2.3.5.gem (100%)
Successfully installed addressable-2.3.5
Fetching: multi_json-1.7.9.gem (100%)
Successfully installed multi_json-1.7.9
Fetching: caldecott-client-0.0.2.gem (100%)
Successfully installed caldecott-client-0.0.2
Fetching: i18n-0.6.5.gem (100%)
Successfully installed i18n-0.6.5
Fetching: tzinfo-0.3.37.gem (100%)
Successfully installed tzinfo-0.3.37
Fetching: minitest-4.7.5.gem (100%)
Successfully installed minitest-4.7.5
Fetching: atomic-1.1.13.gem (100%)
Building native extensions.  This could take a while...
Successfully installed atomic-1.1.13
Fetching: thread_safe-0.1.2.gem (100%)
Successfully installed thread_safe-0.1.2
Fetching: activesupport-4.0.0.gem (100%)
Successfully installed activesupport-4.0.0
Fetching: builder-3.1.4.gem (100%)
Successfully installed builder-3.1.4
Fetching: activemodel-4.0.0.gem (100%)
Successfully installed activemodel-4.0.0
Fetching: cf-uaa-lib-2.0.0.gem (100%)
Successfully installed cf-uaa-lib-2.0.0
Fetching: multipart-post-1.2.0.gem (100%)
Successfully installed multipart-post-1.2.0
Fetching: rubyzip-0.9.9.gem (100%)
Successfully installed rubyzip-0.9.9
Fetching: cfoundry-4.3.6.gem (100%)
Successfully installed cfoundry-4.3.6
Fetching: interact-0.5.2.gem (100%)
Successfully installed interact-0.5.2
Fetching: json_pure-1.8.0.gem (100%)
Successfully installed json_pure-1.8.0
Fetching: mothership-0.5.1.gem (100%)
Successfully installed mothership-0.5.1
Fetching: mime-types-1.25.gem (100%)
Successfully installed mime-types-1.25
Fetching: rest-client-1.6.7.gem (100%)
Successfully installed rest-client-1.6.7
Fetching: uuidtools-2.1.4.gem (100%)
Successfully installed uuidtools-2.1.4
Fetching: cf-5.2.2.gem (100%)
Successfully installed cf-5.2.2
22 gems installed
dpl.2
Preparing deploy
Setting target to https://api.de.a9s.eu...... OK
target: https://api.de.a9s.eu
Authenticating.. .  ... OK
Switching to organization railsgirls... OK
Switching to space heaven... OK
dpl.3
Deploying application
Using manifest file manifest.yml
Uploading railsgirls... OK
Stopping railsgirls... OK
Preparing to start railsgirls... OK
Checking status of app 'railsgirls'...
  0 of 1 instances running (1 starting)
  0 of 1 instances running (1 starting)
  1 of 1 instances running (1 running)
Push successful! App 'railsgirls' available at http://railsgirls.de.a9sapp.eu
Logging out... OK
{% endhighlight %}

This means your are done and good to go!


================================================
FILE: _pages/contributing.md
================================================
---
layout: guide
title: Contributing a Guide
description: "Contribute back to the Rails Girls community with your own guide!"
permalink: contributing
---

# Contributing a Guide

The guides site uses [Jekyll](https://github.com/mojombo/jekyll) to power the site and all the documents are written using [Markdown](https://daringfireball.net/projects/markdown/). To contribute a guide, you just need to follow these simple steps.

1. Fork the [repository on GitHub](https://github.com/railsgirls/railsgirls.github.com) by clicking on the "Fork" button.
2. Do a `git clone` of your fork.

## If you want to add a new guide:

- Create a file named `guide_name.md` inside the `_pages` directory of your fork.
- In this file, you'll need to add some YAML front matter at the top of the file so it looks like the following example, taken from this guide that you are currently viewing:

    <pre>
    ---
    layout: guide
    title: Contributing a Guide
    permalink: contributing
    ---</pre>

You can follow the structure of our [Rails Girls App Tutorial](https://github.com/railsgirls/railsgirls.github.com/blob/master/_pages/app.md).

## If you want to improve an existing guide:
Make the change in the file you want to change! You don't need to make a new file if you want to change something in an existing file.

## Then...

1. Commit this new guide to your Git repo.
2. After you commit, push that to your fork.
3. You can now open a pull request explaining your guide. That's it!

Thanks so much for taking the time to help us make Rails Girls awesome.


================================================
FILE: _pages/deployment/anynines.md
================================================
---
layout: main_guide
title: Rails Girls on anynines
description: "Deploy your app to Anynines by following this guide."
permalink: deployment/anynines
---

# Put your app online with anynines

*Created by Floor Drees, [@floordrees](https://twitter.com/floordrees)*

{% coach %}
Talk about the benefits of deploying to anynines vs utilising US data centers.
{% endcoach %}

### Get yourself some anynines

1. [Create an anynines account](https://anynines.com/).

2. [Download and install the Command Line Interface](https://anynines.zendesk.com/entries/60241846-How-to-install-the-CLI-v6) to interact with anynines.

3. Now select the anynines api endpoint as target and authenticate using your user credentials:

{% highlight sh %}
cf api https://api.de.a9s.eu
cf login -u [your@email] -p [yourpassword]
{% endhighlight %}


Or if that doesn't work for you, use:

{% highlight sh %}
cf login
{% endhighlight %}

... which will prompt you for your email address and password.

Wonder what that `cf` stands for? It's short for [Cloud Foundry](https://www.cloudfoundry.org/), a system anynines is using behind the scenes.

### Push your app online

Let's push this source code from your local machine to anynines:
{% highlight sh %}
$> cf push [application-name-of-your-choosing]
{% endhighlight %}

This will fail miserably since the example application needs a MySQL database to start. So, lets create one! The command below will create a MySQl service with a free service plan. After the plan name you have to specify a name for the service instance. This name will be used for further commands to refer to this service instance:

$> cf create-service mysql Pluto-free [service-name-you-can-choose]

(Really, you can use any name. Make it count!)

Next, binding the MySQL service instance to the application, to grant the application access to the MySQL instance, type:
{% highlight sh %}
$> cf bind-service [app-name-you-have-chosen-above] [service-name-you-have-chosen-above]
{% endhighlight %}

Finally we have to restart the application to make sure the service binding takes effect:
{% highlight sh %}
$> cf restart [app-name-you-have-chosen-above]
{% endhighlight %}

You will see this:
{% highlight sh %}
Creating service postgresql-d2197... OK
Binding postgresql-d2197 to railsgirls... OK
{% endhighlight %}

Ending with... `Push successful! App 'railsgirls' available at railsgirls.de.a9sapp.eu`. Score!

### Version Control

We need to add our new code to version control. You can do this by running the following in the terminal:

{% highlight sh %}
git status
git add .
git commit -m "add anynines deployment"
{% endhighlight %}

{% coach %}
This would be a great time to talk about version control systems and git, if you haven't already.
{% endcoach %}

### Help

You can check all available cf sub-commands by typing `cf help`.
In case your terminal does not have all the answers, the anynines team probably does. Just shoot them a mail at support@anynines.com.

Happy deploying!


================================================
FILE: _pages/deployment/digital-ocean.md
================================================
---
layout: main_guide
title: Rails Girls on DigitalOcean
description: "Deploy your app to DigitalOcean by following this guide."
permalink: deployment/digitalocean
---

# Put Your App Online With DigitalOcean App Platform

*Created by [Colin Alston](https://github.com/calston)*

## Change the production database

Locally your app uses SQLite as the database to store your ideas. It's easier to use another database on DigitalOcean deploys. To deploy with DigitalOcean we'll change the database in production to use PostgreSQL.

### Install the pg gem

Open the `Gemfile` file in your Text Editor and change the following line:

{% highlight ruby %}
gem "sqlite3"
{% endhighlight %}

into these lines:

{% highlight ruby %}
group :development do
  gem "sqlite3"
end
group :production do
  gem "pg"
end
{% endhighlight %}

Next, run the command below to setup the new database gem:

{% highlight sh %}
bundle install --without production
{% endhighlight %}

### Update the database configuration

Up next, you'll need to change the database configuration for the production environment.

{% coach %}
Explain what the different Rails environments are. What is "production"?
{% endcoach %}

Open the `config/database.yml` file in your Text Editor. Change the following lines in the file:

{% highlight yaml %}
production:
  <<: *default
  database: storage/production.sqlite3
{% endhighlight %}

to these lines:

{% highlight yaml %}
production:
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  database: railsgirls_production
  username: railsgirls
  password: <%= ENV["RAILSGIRLS_DATABASE_PASSWORD"] %>
{% endhighlight %}

Save the changes in Git by creating a new commit. We'll need to update our app in Git to deploy these changes.

{% highlight sh %}
git add .
git commit -m "Use PostgreSQL as the production database"
{% endhighlight %}

## Create an account

Head to [https://www.digitalocean.com/go/app-platform](https://www.digitalocean.com/go/app-platform) and sign up for the 60 day free trial.

![Trial page](/images/digitalocean/1.png)

Sign up using Github to link your account

![Github Authorization](/images/digitalocean/githuboauth.png)

You will need a credit card but will receive $200 to start with if this is your first time using DigitalOcean.

![Complete signup](/images/digitalocean/2.png)

## Create an application

Click on `Deploy a web application` to get started.

![Deploy a web application](/images/digitalocean/create-app-1.png)

Choose "Deploy your web app" to add an existing GitHub repository

![Deply source](/images/digitalocean/create-app-2.png)

Authorize DigitalOcean to read your repositories

![Authorize DigitalOcean](/images/digitalocean/create-app-3.png)

Select the repository for your application

![Choose repo](/images/digitalocean/create-app-4.png)
![Choose branch](/images/digitalocean/create-app-5.png)

Click `Next` to continue then `Edit Plan` to ensure we use the appropriate resources. We will start with a Basic plan and the smallest container size which should be sufficient.

![Container size](/images/digitalocean/create-app-7.png)

Continue through the next steps until the end. We should not need to change anything else.

![Environment](/images/digitalocean/create-app-8.png)
![Region](/images/digitalocean/create-app-9.png)

## Deploying our Rails application

Wait for the application to build, you can view realtime logs of the process while it happens.

![Build](/images/digitalocean/building.png)

If all went well you should see your application is available, however it still needs to be initialized and have a database added.

![Deployment](/images/digitalocean/deploy.png)

Click on `Create` and `Create/Attach Database` to connect a PostgreSQL database.

![Database](/images/digitalocean/database.png)

The application will automatically be configured with the database credentials

## Configuration
You can now head to the `Console` to access your application container and setup the database.

Type `rails db:migrate` into the terminal and press Enter. You should see the database being setup with the Rails schema.

![Migrate](/images/digitalocean/migrate.png)

If all went well you should now be able to click on the `Live App` button which links to the live server.

![Tada](/images/digitalocean/fin.png)

## Conclusion

Your Rails app is now running in the cloud on DigitalOcean. You can push your changes to GitHub and they'll show up automatically the live URL after some time. Share the URL to show off your app to your friends!

Keep an eye out when your free credits run out and delete the app if you no longer need it.


================================================
FILE: _pages/deployment/engineyard.md
================================================
---
layout: main_guide
title: Rails Girls on Engine Yard
description: "Deploy your app to Engine Yard by following this guide."
permalink: deployment/engineyard
---

# Put Your App Online With Engine Yard

*Created by Mary Jenn, [@mfjenn](https://twitter.com/mfjenn)*

#### Ensure You're Using PostGres for Your Database

You'll need to get your database to work on Engine Yard, which uses a different database than the Rails default. Please change the following in the Gemfile:


		gem 'sqlite3'


to

		group :development do
			gem 'sqlite3'
		end


		group :production do
			gem 'pg'
		end



Run `bundle install --without production` to setup your dependencies.

#### Version Control Systems

You need to add your app to your Git repository. You can do this by running the following in the terminal:


>	`git init`

>	`git add .`

>	`git commit -m "initial commit"`


{% coach %}
This would be a good time to talk about version control systems and git.
{% endcoach %}

### Be Sure to Have a Rails Application in a Repository on Github

You will need to have a GitHub account and a repo we can pull an app from. Follow these directions on [GitHub](https://help.github.com/articles/create-a-repo) to create a repo and push your app to it. If you do not have a working Rails application, you can fork [Engine Yard's sample todo app](https://github.com/engineyard/todo) to your own repo. A coach can walk you through this if you need help.

### Sign up for a Free Trial Engine Yard Account

Go to Engine Yard's [Website](https://www.engineyard.com/) and click on "GET STARTED FREE" to sign up for your Free 500 Hour Trial. The sign up will send you a confirmation email, so go check your email, click on the link and sign in to your account. Click on the link under "Your available applications" that says "Engine Yard Cloud". This will take you to your dashboard.

### Create your Engine Yard Cloud account

1. 	Choose a name for your account. We suggest picking something relevant to who you are, either as a developer, or as an organization if you will be having collaborators. Click the button "Start Trial"

2. 	Feel free to explore what is in the drop downs, but let's go with the defaults for now, since they are in line with a basic Rails app.

3. 	In the box labeled "Git Repository URI", paste the URI from your Github repo. Be sure to use the URI from the SSH version of your application. HINT: The format should be the same as the placeholder text on your Engine Yard application page (or like this: "git@github.com:mfjenn/blogotron.git")


### Putting Your Deploy Key in Place

You should now be on a page that says "Allow Engine Yard access to private repository".

1.	Copy the block of text in the box and go to your GitHub settings page.
2.	Go to the SSH page
3.	Click on the button that says "add a key"
4.	Paste the block of text from your Engine Yard page here. Save it
5.	Go back to your Engine Yard Page and Click the button that says, "My deploy key is in place".

{% coach %}
Talk about the difference between private and public repos and when to use either.
{% endcoach %}

### Creating and Configuring Your Environment

Once you click the "My deploy key is in place" button, you will be taken to a page that says, "Create New Environment for (Your Account Name) App". It is here where we will configure your application. Feel free to explore all the options in the drop downs, but let's use the defaults for now. You do not need to set a domain name.
*	Click the button that says, "Create Environment".

#### Environment Setup

On this page, let's select the staging configuration.
*	Click "Boot This Configuration". You will go to a new page where you see several status bars moving. Our Platform is provisioning your instances. We need to wait till these turn to green dots. This usually takes about 10 minutes, so does anyone need to take a break? It's a good time to go grab some water or a coffee.

{% coach %}
Talk about Staging vs. Production, and why it's important to have replicas. Talk about what is a master & Slave. How does Engine Yard's Failover work? Why is that important?
{% endcoach %}


#### Deploying Your Application

1.	Once all of the lights are green, click "Deploy".
2.	Once you see the phrase "YOUR NAME successfully deployed HEAD" you will know it has been deployed! Congratulations!
3.	Click on the link that says "View your application" to visit your application online.
4.	If you get a red notification that your deploy failed, we just have some debugging to do. Raise your hand and a coach can come over to to help.


#### Stopping Your Instances to Save Your Hours

Once you've got your app up & running, be sure to click the "stop" button to stop the instances so that your don't burn through all of your hours. You can always start them again.

### Additional Resources
*	[A video tutorial](https://support.cloud.engineyard.com/entries/21009937-Video-Tutorial-Set-up-an-Account-and-Deploy-an-Application)

*	[Another Tutorial From the Engine Yard Site](https://support.cloud.engineyard.com/entries/20996751-Tutorial-How-to-Deploy-the-ToDo-Application-on-a-Trial-Account)


================================================
FILE: _pages/deployment/fly-io.md
================================================
---
layout: main_guide
title: Put your app online with Fly.io
description: "Deploy your app to Fly.io by following this guide."
permalink: deployment/fly-io
---

# Put your app online with Fly.io

In this guide you'll deploy your app with [Fly.io](https://fly.io) to make it available to everyone online. After this guide you can share the link with your friends and family to show what you have created during this workshop.

Deploying a single small app with Fly.io is free, with some limitations.

{% coach %}
Talk about the benefits of deploying to Fly.io versus traditional servers.
{% endcoach %}

## Change the production database

Locally your app uses SQLite as the database to store your ideas. It's easier to use another database on Fly.io deploys. To deploy with Fly.io we'll change the database in production to use PostgreSQL.

### Install the pg gem

Open the `Gemfile` file in your Text Editor and change the following line:

{% highlight ruby %}
gem "sqlite3"
{% endhighlight %}

into these lines:

{% highlight ruby %}
group :development do
  gem "sqlite3"
end
group :production do
  gem "pg"
end
{% endhighlight %}

Next, run the command below to setup the new database gem:

{% highlight sh %}
bundle install --without production
{% endhighlight %}

### Update the database configuration

Up next, you'll need to change the database configuration for the production environment.

{% coach %}
Explain what the different Rails environments are. What is "production"?
{% endcoach %}

Open the `config/database.yml` file in your Text Editor. Change the following lines in the file:

{% highlight yaml %}
production:
  <<: *default
  database: storage/production.sqlite3
{% endhighlight %}

to these lines:

{% highlight yaml %}
production:
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  database: railsgirls_production
  username: railsgirls
  password: <%= ENV["RAILSGIRLS_DATABASE_PASSWORD"] %>
{% endhighlight %}

Save the changes in Git by creating a new commit. We'll need to update our app in Git to deploy these changes.

{% highlight sh %}
git add .
git commit -m "Use PostgreSQL as the production database"
{% endhighlight %}

## Create a Fly.io account

Visit the [Fly.io sign up page](https://fly.io/app/sign-up) and fill in the form to make a new user account.

On the next screen, click the "Try Fly.io for free" link. You do not need to enter your Credit Card to use Fly.io for free.

## Install the Fly.io CLI

To deploy apps with Fly.io, you'll need to use the Fly.io CLI: a tool for the Terminal app.

Follow the [installation instructions on this Fly.io docs page](https://fly.io/docs/hands-on/install-flyctl/). Continue with this guide when the Fly.io CLI has been installed.

## Login to the Fly.io CLI

Run the following command to connect your Fly.io user account to your laptop and deploy your app with Fly.io in the Terminal app.

{% highlight sh %}
flyctl auth login
{% endhighlight %}

It will open your Browser with a new tab/window. Either login to your Fly.io user account you created earlier, or click the button starting with "Continue as ...". You are now logged into Fly.io with the CLI.

## Configure the app

Run the following command create the necessary configuration in your app to deploy it.

{% highlight sh %}
fly launch
{% endhighlight %}

When prompted for questions, enter or select the following:

- Choose an app name:
    - Enter: railsgirls-yourname
    - Change "yourname" to your (nick)name.
- Choose a region for deployment:
    - Choose the region closest to you with the arrow keys and then press <kbd>Enter</kbd>.
- Would you like to set up a Postgresql database now?
    - Press <kbd>y</kbd> and then press <kbd>Enter</kbd>.
- Select configuration:
    - Choose "Development" from the list.
- Would you like to set up an Upstash Redis database now?:
    - Press <kbd>n</kbd> and then press <kbd>Enter</kbd>.

Your app is now configured to deploy with Fly.io. You'll need to commit these changes before you can deploy. Commit your changes with this command:

{% highlight sh %}
git add .
git commit -m "Configure for Fly.io deployment"
{% endhighlight %}

## Deploy the app in the future

If you made any new changes to your app and want to deploy the changes in the future, run the following command:

{% highlight sh %}
fly deploy
{% endhighlight %}

You'll see a lot of text being printed about the results of the steps needed to deploy the app. Wait until it's done. It should say "v0 deployed successfully".

## View your deployed app

Your app should now be deployed. This means it's online for people to see. To know where you can view it, run the following command to open it in your Browser:

{% highlight sh %}
fly open
{% endhighlight %}

You now have your first app deploy! Congratulations! Share the link you see in your Browser's address bar!

---

You do not need to deploy your app on another services. Continue with the next numbered guide in the list below.


================================================
FILE: _pages/deployment/heroku.md
================================================
---
layout: main_guide
title: Put your app online with Heroku
description: "Deploy your app to Heroku by following this guide."
permalink: deployment/heroku
---

# Put your app online with Heroku

*Created by Terence Lee, [@hone02](https://twitter.com/hone02)*

## Get Heroku

Follow steps "Introduction" and "Set up" of the
[Getting Started on Heroku with Ruby][heroku-guide] to sign up, install the
Heroku CLI, and login.

{% coach %}
Talk about the benefits of deploying to Heroku vs traditional servers.
{% endcoach %}

[heroku-guide]: https://devcenter.heroku.com/articles/getting-started-with-ruby#introduction

## Updating our database

First, we need to get our database to work on Heroku, which uses a different
database. Please change the following in the Gemfile:

{% highlight ruby %}
gem "sqlite3"
{% endhighlight %}

to

{% highlight ruby %}
group :development do
  gem "sqlite3"
end
group :production do
  gem "pg"
end
{% endhighlight %}

Run `bundle install --without production` to setup your dependencies.

Next, update the `config/database.yml` file.
Change the following lines in the file:

{% highlight yaml %}
production:
  <<: *default
  database: storage/production.sqlite3
{% endhighlight %}

to these lines:

{% highlight yaml %}
production:
  adapter: postgresql
  encoding: unicode
  database: railsgirls_production
  pool: 5
{% endhighlight %}

Then save the changes in Git by creating a new commit. We'll need to update our app in Git to deploy the new version to Heroku.

{% highlight sh %}
git add .
git commit -m "Use postgres as production database"
{% endhighlight %}

{% coach %}
You can talk about RDBMS and the different ones out there, plus include some details on Heroku's dependency on PostgreSQL.
{% endcoach %}

## Deploying your app

### App creation

We need to create our Heroku app by typing `heroku create` in the terminal and
see something like this:

{% highlight sh %}
Creating app... done, ⬢ young-reaches-87845
https://young-reaches-87845.herokuapp.com/ | https://git.heroku.com/young-reaches-87845.git
{% endhighlight %}

In this case "young-reaches-87845" is your app name.

### Pushing the code

Next we need to push our code to heroku by typing `git push heroku master`.
You'll see push output like the following:

{% highlight sh %}
Counting objects: 115, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (97/97), done.
Writing objects: 100% (115/115), 25.62 KiB | 0 bytes/s, done.
Total 115 (delta 10), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.2.4
remote: -----> Installing dependencies using bundler 1.11.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Fetching gem metadata from https://rubygems.org/..........
remote:        Fetching version metadata from https://rubygems.org/...
remote:        Fetching dependency metadata from https://rubygems.org/..
remote:        Installing concurrent-ruby 1.0.2
...
remote: -----> Launching...
remote:        Released v5
remote:        https://young-reaches-87845.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/young-reaches-87845.git
 * [new branch]      master -> master
{% endhighlight %}

You'll know the app is done being pushed, when you see the "Launching..." text like above.

### Migrate database

Next we need to migrate our database like we did locally during the workshop:

{% highlight sh %}
heroku run rails db:migrate
{% endhighlight %}

When that command is finished being run, you can hit the app based on the url.
For this example app, you can go to <https://young-reaches-87845.herokuapp.com/>.
You can also type `heroku open` in the terminal to visit the page.

### Closing notes

Heroku's platform is not without its quirks. Applications run on Heroku live
within an ephermeral environment — this means that (except for information
stored in your database) any files created by your application will disappear
if it restarts (for example, when you push a new version).

###### [Ephemeral filesystem][ephemeral-filesystem]

> Each dyno gets its own ephemeral filesystem, with a fresh copy of the most
> recently deployed code. During the dyno’s lifetime its running processes can
> use the filesystem as a temporary scratchpad, but no files that are written
> are visible to processes in any other dyno and any files written will be
> discarded the moment the dyno is stopped or restarted. For example, this
> occurs any time a dyno is replaced due to application deployment and
> approximately once a day as part of normal dyno management.

In the [App](/app) tutorial the ability to attach a file to the Idea record is
added, which results in new files being written to your applications
`public/uploads` folder. The ephemeral storage in Heroku can be seen with the
following steps:

1. Launch the app with `heroku open`
2. Add a new Idea with an image
3. Restart the application by running `heroku restart`
4. Go back to your Idea and reload the page - the image should no longer be visible

[ephemeral-filesystem]: https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

#### Working around Ephemeral Storage

Obviously this doesn't seem to be useful if you were running a real life
application, but there are ways to work around this which is commonly used by
a lot of popular websites.

The most common method is to use an external asset host such as Amazon S3 (Simple
Storage Service) or Rackspace CloudFiles. These services provide (for a low cost
- usually less then $0.10 per GB) storage 'in the cloud' (meaning the files
could potentially be hosted anywhere) which your application can use as persistent storage.

While this functionality is a bit out of scope for this tutorial there are some
resources available which you can use to find your way:

* [How to: Make Carrierwave work on Heroku](https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Make-Carrierwave-work-on-Heroku)
* [Amazon S3 – The Beginner’s Guide](https://www.hongkiat.com/blog/amazon-s3-the-beginners-guide/)

As always if you require any more information or assistance your coaches will be able to assist.


================================================
FILE: _pages/deployment/openshift.md
================================================
---
layout: main_guide
title: Rails Girls on OpenShift
description: "Deploy your app to OpenShift by following this guide."
permalink: deployment/openshift
---

# Put Your App Online With OpenShift

*Created by Katie Miller, [@codemiller](https://twitter.com/codemiller)*

### Get OpenShift

OpenShift is a cloud computing Platform as a Service (PaaS) that makes it easy to deploy apps online. It is open source and written in Ruby.

To get started [create an OpenShift Online account](https://www.openshift.com/app/account/new), which allows you to put three apps online for free. Once you are signed up, install the OpenShift RHC Client Tools by running these commands in a terminal and following the prompts:

{% highlight sh %}
gem install rhc
rhc setup
{% endhighlight %}

The above instructions assume you installed Ruby using RVM or RailsInstaller. If you used another approach, there is more info about installing RHC for different set-ups in [this guide](https://www.openshift.com/developers/rhc-client-tools-install) (you may need to do `sudo gem install rhc`).

{% coach %}
Talk about the benefits of deploying to a PaaS such as OpenShift, as opposed to traditional servers. Discuss SSH and why we need to upload a public key to communicate securely.
{% endcoach %}

### Preparing your app

#### Create OpenShift application

We are going to create an OpenShift Ruby application with a PostgreSQL database, using a sample OpenShift Rails application as our starting point. Before we do that, in your terminal change to the parent directory of the one containing your `railsgirls` code, probably called `projects`. The `cd` command below will take you there if you are currently in your `railsgirls` directory; if not, substitute another `cd` command.

{% highlight sh %}
cd ..
pwd
{% endhighlight %}

The output from the `pwd` or 'present working directory' command should show you are now in the `projects` directory (or whatever your parent directory was called). To create the OpenShift app in the cloud and make a local copy of its contents, run the following command in your terminal.

_NB: This command is for those using Ruby 2.x and Rails 4. If you have installed Ruby 1.9.x, replace `ruby-2.0` in the command with `ruby-1.9`. For Rails 3, change the `--from-code` URL to `https://github.com/openshift/rails-example.git`._

{% highlight sh %}
rhc app create openshiftapp ruby-2.0 postgresql-9.2 --from-code=https://github.com/openshift/rails4-example.git
{% endhighlight %}

If you see a message like `Are you sure you want to continue connecting (yes/no)?`, type `yes` and press enter.

The terminal output should include a URL; open a browser window and go to the application URL to view the sample Rails application (the URL will have the form https://openshiftapp-*yourdomain*.rhcloud.com).

{% coach %}
Explain what Git is and why we use version control systems.
{% endcoach %}

#### Add version control

We now have a sample app running in the cloud, but we actually need only a few pieces from its codebase. Before we copy across the bits we need, we should put our Rails Girls app under version control with Git.

Change back to your `railsgirls` app directory and initialize it as a Git repository with the following commands:

{% highlight sh %}
cd railsgirls
git init
{% endhighlight %}

We don't want the pictures uploaded during app development to be part of our repository, so run the following command to instruct Git to ignore them:

{% highlight sh %}
echo "public/uploads" >> .gitignore
{% endhighlight %}

Add and commit all your app files to the Git repository with the following commands:

{% highlight sh %}
git add --all
git commit -m "First commit of Ideas app"
{% endhighlight %}

{% coach %}
Explain the Git commands used and .gitignore.
{% endcoach %}

#### Copy sample app code

We need the `.openshift` directory and `config/database.yml` file from the sample application for our Rails app to run on OpenShift. Copy these from the `openshiftapp` directory to the `railsgirls` directory. You can use Windows Explorer or another graphical file system tool to do this if you like, or alternatively run the following commands from the `railsgirls` directory in your terminal:

<div class="os-specific">
   <div class="mac nix">
{% highlight sh %}
cp -r ../openshiftapp/.openshift .
cp ../openshiftapp/config/database.yml config
{% endhighlight %}
  </div>

  <div class="win">
{% highlight sh %}
xcopy /e /i ..\openshiftapp\.openshift .openshift
xcopy /y ..\openshiftapp\config\database.yml config
{% endhighlight %}
  </div>
</div>

Check that the copying has worked by looking in the `railsgirls` app directory. There should now be a subdirectory called `.openshift`. Open the file `config/database.yml`; it should now contain OpenShift environment variables such as `OPENSHIFT_APP_NAME`. If your `database.yml` file does not contain variables like this, try opening `.openshift/config/database.yml` or `openshiftapp/config/database.yml` in your editor and copying across the contents of the file. 

Add and commit the new and changed files in Git with the below commands.

{% highlight sh %}
git add --all
git commit -m "Added OpenShift config"
{% endhighlight %}

#### Change database

The next step is to change our Rails Girls app database from SQLite to PostgreSQL. Open your application's `Gemfile` and replace:

{% highlight ruby %}
gem 'sqlite3'
{% endhighlight %}

with

{% highlight ruby %}
gem 'sqlite3', :group => [:development, :test]
gem 'pg', :group => [:production]
{% endhighlight %}

Do a bundle to set up your dependencies:

{% highlight sh %}
bundle install --without production
{% endhighlight %}

On some platforms, this may generate platform-specific versions of your Gems that cause issues when you push your app to the cloud. To prevent this, open your `Gemfile.lock` file and check the versions of the 'sqlite3' and 'pg' Gems. If they have a platform-specific suffix, such as `-x86-mingw32`, remove this (eg. change `pg (0.16.0-x86-mingw32)` to `pg (0.16.0)` and `sqlite3 (1.3.8-x86-mingw32)` to `sqlite3 (1.3.8)`). Save and close the file, and run the above bundle command again before continuing.

Add and commit your changes in Git:

{% highlight sh %}
git add --all
git commit -m "Changed production database to PostgreSQL"
{% endhighlight %}

{% coach %}
Talk about relational databases and the differences between SQLite and PostgreSQL.
{% endcoach %}

### Deploy app to OpenShift

We are now ready to deploy the Rails Girls app to OpenShift. We need to tell our Git repository where to push the code. To get the location of your OpenShift code repository, run the following command, and copy the Git URL from the output.

{% highlight sh %}
rhc app show openshiftapp
{% endhighlight %}

Now run the following commands, replacing the SSH string with your Git URL. We are using '-f' for force here because we are happy to wipe away the history of the current OpenShift repository, which contains the sample Rails app. When you are pushing future changes, you can just use 'git push'.

{% highlight sh %}
git remote add openshift ssh://0123456789abcdef01234567@openshiftapp-yourdomain.rhcloud.com/~/git/openshiftapp.git/
git push -f --set-upstream openshift master
{% endhighlight %}

Refresh the app in your browser to see the result.

{% coach %}
Talk about Git remotes.
{% endcoach %}

### Extra credit

Congratulations - your Rails application is now online for the whole world to admire. The following sections explain optional further steps you can take to improve and share your app. 

#### Persist uploaded images

The app should be looking pretty good now, but there is an issue lurking because of the ephemeral nature of the deployment. When we push a new version of the application, anything stored within OpenShift's copy of the repo will be wiped to make way for the new files. This includes the images uploaded by users. To fix this, we can store these files in a persistent directory on OpenShift instead. The filepath of the location we need is stored in an environment variable.

{% coach %}
Explain the motivation for using environment variables.
{% endcoach %}

The directory where uploaded pictures are currently stored is within the app repository, so it will be deleted when we rebuild. To switch the uploads directory to one that will persist, open `app/uploaders/picture_uploader.rb` and replace

{% highlight ruby %}
def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
{% endhighlight %}

with

{% highlight ruby %}
def store_dir
  prefix = ENV['OPENSHIFT_DATA_DIR'] ? "#{ENV['OPENSHIFT_DATA_DIR']}/" : ""
  "#{prefix}uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

def url
  return "/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/#{File.basename(file.path)}" if ENV['OPENSHIFT_DATA_DIR'] && file
  super
end
{% endhighlight %}

Now uploaded images will be stored in a persistent directory, but they will still be available through the same URL as what we were using previously. To make this work, we also need to add a symbolic link on the filesystem from the repository location to the real storage location. To do this, open `.openshift/action_hooks/build` and add the following code:

{% highlight sh %}
mkdir -p $OPENSHIFT_DATA_DIR/uploads
ln -sf $OPENSHIFT_DATA_DIR/uploads $OPENSHIFT_REPO_DIR/public/uploads

{% endhighlight %}

This action hook code will run every time the OpenShift app is built, so the link between the directories will always be there when it's needed.

Commit your changes and push them to the cloud:

{% highlight sh %}
git add --all
git commit -m "Added OpenShift environment variables"
git push
{% endhighlight %}

The images you uploaded before making this change will no longer display, but anything uploaded now will stick around between app rebuilds.

{% coach %}
Explain symbolic links.
{% endcoach %}

#### Push code to GitHub

Now that your application is under source control with Git, you may also wish to share a copy with others on a Git repository website such as GitHub. To push your code to a GitHub repository, [create a repository](https://github.com/new) on GitHub and copy the HTTPS string (something like *https://github.com/username/reponame.git*).

Navigate to your OpenShift app repository in the terminal and enter the following commands, replacing the HTTPS location with the string you copied:

{% highlight sh %}
git remote add github https://github.com/username/reponame.git
git push github master
{% endhighlight %}

The 'master' branch of the local copy of your repository will be pushed to GitHub. Go to the GitHub website to check it out.

{% coach %}
Talk about Git branches and the benefits of open source code.
{% endcoach %}

### Conclusion

Your Rails app is now running in the cloud on [OpenShift](https://www.openshift.com/developers). You can push whatever other changes you like and share the URL to show off your app to your friends.


================================================
FILE: _pages/deployment.md
================================================
---
layout: main_guide
title: Put your app online
description: "Publish your app online on one of the many available web hosting services."
permalink: deployment
---

# Put your app online

{% include main-guide-intro.html %}

Now that you have your very first app made, let's share it with others by putting it online!

Once you're done with one of the following guides, you'll have a URL that people can enter in their browser and see what you made today. During the workshop you can continue working on your app (by following these guides), and deploying new and improved versions of your app.

There are many services that can host your app. They all are slightly different. Ask your coach which service they recommend.

{% coach %}
Please help choose the best, and possibly free, service to deploy the app. Preferably a PaaS like Heroku.
{% endcoach %}


================================================
FILE: _pages/design-using-html-and-css-chinese.md
================================================
---
layout: guide
title: 使用HTML和CSS美化你的应用
permalink: design-html-css-chinese
---

1.美化header样式

+ 打开文件 `app/assets/stylesheets/application.css` 并在最底端添加:

    ```
    .navbar {
      min-height: 38px;
      background-color: #f55e55;
    }
    ```

    刷新页面,查看样式有什么变化。 此处解释什么是css选择器,学员可以尝试修改header的颜色,字体等。 简单的颜色选取参考网站: <https://color.uisdc.com/>

    **教练:**解释`display`的属性,什么是内联元素,什么是块级元素

+ 在文件底部加入下面的代码:

    ```
    .navbar a.brand { font-size: 18px; }
    .navbar a.brand:hover {
     color: #fff;
     background-color: transparent;
     text-decoration: none;
    }
    ```

    **教练:**解释css中链接的四种状态


2.美化表格样式

 + 对于表格,我们可以使用[Bootstrap](https://www.bootcss.com/)的表格样式。打开`app/views/ideas/index.html.erb`文件,找到:

   ```
   <table>
   ```

   将其改为

   ```
   <table class="table">
   ```

 + 修改图片大小,找到这段代码

     ```
     <%= image_tag(idea.picture_url, :width => 600) if idea.picture.present? %>
     ```

     尝试修改width


 + 打开文件`app/assets/stylesheets/ideas.css.scss`,加入以下代码:

  ```
  .container a:hover {
    color: #f55e55;
    text-decoration: none;
    background-color: rgba(255, 255, 255, 0);
  }
  ```


 + 尝试为页面添加背景图片,使用`background-image`属性,背景纹理资源参考此网站 <https://www.toptal.com/designers/subtlepatterns/>


3.footer样式调整

  + 打开文件 `app/assets/stylesheets/application.css` 并在最底端添加:

    ```
    footer {
      background-color: #ebebeb;
      padding: 30px 0;
    }
    ```

    尝试在`footer`中加入更多内容,并调整位置

4.按钮样式

  + 打开<http://localhost:3000/ideas/new>页面,可以看到页面上的`Create Idea`按钮。

   在文件`app/assets/stylesheets/ideas.css.scss`最后加入

   ```
   .container input[type="submit"] {
      height: 30px;
      font-size: 13px;
      background-color: #f55e55;
      border: none;
      color: #fff;
    }
   ```

   **教练:**解释css中`border`的使用,学员可以尝试修改按钮样式,加圆角,阴影,颜色等。


================================================
FILE: _pages/design.md
================================================
---
layout: main_guide
title: Style the idea pages using HTML and CSS
description: "Make your app look even better using Bootstrap by styling the idea pages."
permalink: design
---

# Style the idea pages using HTML and CSS

*Originally created by Alex Liao, @alexliao*

{% include main-guide-intro.html %}

## Style the idea list page

The default Rails scaffolding allow us to build pages very quickly and get our app working. The design could use some work. For this we're going to be using [Bootstrap](https://getbootstrap.com/docs/5.2/) again. We'll be using some existing Bootstrap classes to make our own components, style links and buttons.

Open `app/views/ideas/index.html.erb` in your Text Editor and replace all the lines with these lines:

{% highlight erb %}
<p style="color: green"><%= notice %></p>

<h1>Ideas</h1>
<%= link_to "Add a new idea", new_idea_path, class: "btn btn-primary mb-3" %>

<div class="list-group w-auto">
  <% @ideas.each do |idea| %>
    <%= render idea %>
  <% end %>
</div>
{% endhighlight %}

This alone isn't all the styling we'll need, but this will show all the ideas in a nice list in a moment. At the top we'll have a new blue button with the label "Add a new idea".

Open `app/views/ideas/_idea.html.erb` in your Text Editor and replace all the lines with these lines:

{% highlight erb %}
<div id="<%= dom_id idea %>" class="list-group-item list-group-item-action d-flex gap-3 py-3">
  <div class="d-flex flex-column gap-2 w-100">
    <h2><%= link_to idea.name, idea_path(idea) %></h2>
    <p><%= idea.description %></p>
    <small class="opacity-50 text-nowrap">Last updated <%= time_ago_in_words idea.updated_at %></small>
  </div>
  <%= image_tag(idea.picture_url, width: 150, height: 150, class: "img-thumbnail flex-shrink-0") if idea.picture? %>
</div>
{% endhighlight %}

This will style each idea in the list to show their idea name as a link to the idea itself, it shows when the idea was last updated, the idea description and a thumbnail of the picture you uploaded.

Visit the <http://localhost:3000/ideas> page to see your new idea app design.

{% coach %}
Explain how the design works line by line. What is HTML, what is CSS and what parts are Bootstrap?
{% endcoach %}

## Style the idea detail page

Click the title of an idea, and you will be brought to the details page of the idea. This still partially uses scaffold generated by Rails, and may look a bit broken right now. Let's improve the design.

Open `app/views/ideas/show.html.erb` in your text editor and replace all lines with

{% highlight erb %}
<p style="color: green"><%= notice %></p>

<div id="<%= dom_id @idea %>" class="d-flex gap-3 py-3">
  <div class="d-flex flex-column gap-2 w-100">
    <h1><%= @idea.name %></h1>
    <p><%= @idea.description %></p>
    <small class="opacity-50 text-nowrap">Last updated <%= time_ago_in_words @idea.updated_at %></small>
  </div>
  <%= image_tag(@idea.picture_url, width: 150, height: 150, class: "img-thumbnail flex-shrink-0") if @idea.picture? %>
</div>

<div class="d-flex gap-3 py-3">
  <%= link_to "Edit this idea", edit_idea_path(@idea), class: "btn btn-primary" %>
  <%= link_to "Back to ideas", ideas_path, class: "btn btn-outline-secondary" %>
  <%= button_to "Destroy this idea", @idea, method: :delete, class: "btn btn-danger", form: { data: { turbo_confirm: "Are you sure?" } } %>
</div>
{% endhighlight %}

The new page should look a lot better and a lot like how the ideas are shown on the index page. The actions you can perform on the idea now also are shown in highly visible buttons below the idea details.

{% coach %}
Explain how the design works line by line. What is HTML, what is CSS and what parts are Bootstrap?
{% endcoach %}

## References

To style the pages we've used the following Bootstrap components. Check out the documentation to learn more.

- [Bootstrap list groups](https://getbootstrap.com/docs/5.2/components/list-group/)
- [Bootstrap buttons](https://getbootstrap.com/docs/5.2/components/buttons/)
- [Bootstrap images](https://getbootstrap.com/docs/5.2/content/images/)

## What next?

Did the design and styling catch your eye? Do you want to unleash your inner designer and style more pages?

* Use your new knowledge to design the new idea form located at `app/views/ideas/_form.html.erb`
* Add more design to the other pages as you wish.


================================================
FILE: _pages/devise.md
================================================
---
layout: guide
title: Adding Authentication with Devise
description: "Let users of your Rails app sign in using Devise."
permalink: devise
---

# Adding Authentication with Devise

*Created by Piotr Steininger, [@polishprince](https://twitter.com/polishprince). Updated by Ernesto Jimenez, [@ernesto_jimenez](https://twitter.com/ernesto_jimenez)*, and [Hasan Diwan](https://units.d8u.us/twitter?src`=railsgirlsGuide)

**This guide assumes that you have already built a Rails Girls app by** [**following the app development guide**](/app).

## *1.* Add devise gem

{% highlight sh %}
bundle add devise
bundle install
{% endhighlight %}
to install the gem. **Also remember to restart the Rails server**.

## *2.* Set up devise in your app

Run the following command in the terminal.

{% highlight sh %}
rails g devise:install
{% endhighlight %}

## *3.* Configure Devise

Ensure you have defined default url options in your environments files. Open up `config/environments/development.rb` and add this line:
{% highlight ruby %}
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
{% endhighlight %}

before the `end` keyword.

Open up `app/views/layouts/application.html.erb` and add:

{% highlight erb %}
<% if notice %>
  <p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
  <p class="alert alert-danger"><%= alert %></p>
<% end %>
{% endhighlight %}
right above
{% highlight ruby %}
  <%= yield %>
{% endhighlight %}

Open up `app/views/ideas/show.html.erb` and remove the line that says:

{% highlight erb %}
<p id="notice"><%= notice %></p>
{% endhighlight %}

Do the same for `app/views/comments/show.html.erb`. These lines are not necessary as we've put the notice in the `app/views/layouts/application.html.erb` file.

## *4.* Setup the User model

We'll use a bundled generator script to create the User model.
{% highlight sh %}
rails g devise user
rails db:migrate
{% endhighlight %}

{% coach %}
Explain what user model has been generated. What are the fields?
{% endcoach %}

## *5.* Create your first user

Now that you have set everything up you can create your first user. Devise creates all the code and routes required to create accounts, log in, log out, etc.

Make sure your rails server is running, open <http://localhost:3000/users/sign_up> and create your user account.

## *6.* Add sign-up and login links

All we need to do now is to add appropriate links or notice about the user being logged in in the top right corner of the navigation bar.

In order to do that, edit `app/views/layouts/application.html.erb` add:
{% highlight erb %}
<p class="navbar-text float-right">
<% if user_signed_in? %>
  Logged in as <strong><%= current_user.email %></strong>.
  <%= link_to "Edit profile", edit_user_registration_path, class: "navbar-link" %> |
  <%= link_to "Logout", destroy_user_session_path, data: { turbo_method: :delete }, class: "navbar-link"  %>
<% else %>
  <%= link_to "Sign up", new_user_registration_path, class: "navbar-link"  %> |
  <%= link_to "Login", new_user_session_path, class: "navbar-link"  %>
<% end %>
</p>
{% endhighlight %}
right after
{% highlight erb %}
  <ul class="navbar-nav mr-auto">
    <li class="nav-item active">
      <a class="nav-link" href="/ideas">Ideas</a>
    </li>
    ...
  </ul>
{% endhighlight %}

Finally, force the user to redirect to the login page if the user was not logged in. Open up `app/controllers/application_controller.rb` and add:

{% highlight ruby %}
before_action :authenticate_user!
{% endhighlight %}

after `class ApplicationController < ActionController::Base`.

Open your browser and try logging in and out from.

{% coach %}
Talk about the `user_signed_in?` and `current_user` helpers. Why are they useful?
{% endcoach %}

## What next?

* Add extra fields to the User model
* Add relationships between users and ideas
* Restrict users to only be able to edit their own ideas and delete their own comments
* Expand to use roles or permissions (use one of the popular authorization gem like CanCan)


================================================
FILE: _pages/diary-app.md
================================================
---
layout: guide
title: Rails Girls Diary tutorial
permalink: diary-app
---

# Create your first diary app with Ruby on Rails

*Created by Piotr Szotkowski ([chastell](https://chastell.net)) and Tomasz Stachewicz ([tomash](https://tomash.wrug.eu/))*

We will create a little voting app from scratch using a web development framework for Ruby called Rails. Think what your first application should be about – ideally something simple that includes a collection of some sort: e.g., a to-do list, a diary, etc. We’ll use a diary as the base here.

{% coach %}
For the rationale behind this slightly different beginners tutorial, take a look at this [post](http://dotclass.org/rails-girls-warsaw-programme/).
{% endcoach %}


**Make sure you have Rails installed.** [**Follow the installation guide**](/install) to get set up.

### Important

It is important that you select the instructions specific to your operating system - the commands you need to run on a Windows computer are slightly different to Mac or Linux. If you're having trouble check the Operating System switcher at the bottom of the commands. In case you're using a cloud service, you need to run the Linux commands even if you are on a Windows computer.

## Pure HTML

### File and folder

Create a new directory (folder) and create a file named `index.html` in it. Open that file in your editor and web browser.

{% coach %}
Explain that browsers can open local files, only the URL looks stranger than usual.
{% endcoach %}

### HTML skeleton

Start by adding a general skeleton for your HTML by writing the below into the `index.html` file:

{% highlight erb %}
<!doctype html>
<html>
  <head>
    <title>My Little Webapp: Coding Is Magic</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="https://rawgithub.com/krzysztofbialek/Rails-Girls-Warsaw-App/master/style.css" />
  </head>
  <body>
  </body>
</html>
{% endhighlight %}

{% coach %}
Explain the two main parts of HTML, `<head>` and `<body>`. Explain the `<title>` tag and (briefly) `<meta>` , `<link>` and `<script>` if needed. Bootstrap is there so that CSS can be skipped altogether (unless participants want to cover it).
{% endcoach %}

### First visible content

Add the following HTML between the `<body>` and `</body>` tags (feel free to adjust the contents…):

{% highlight erb %}
<h1>My Rails Girls Diary</h1>
  <div>
    <h2>Submitted a Rails Girls application</h2>
      <p>1.02.2014</p>
      <p>Just submitted an application to a Rails Girls workshop. Can’t wait to see whether I’ll get in!</p>
      <h2>Got in!</h2>
      <p>15.02.2014</p>
      <p>Received an email that my application got accepted! I’ll be at a RG workshop next week!</p>
    <h2>The first day starts…</h2>
      <p>22.02.2014</p>
      <p>Today is the first day of the Rails Girls workshop. My coach is quite strange but it seems we all have Rails installed now and can start learning.</p>
  </div>
{% endhighlight %}

These are your first three diary entries. Note how the different tags get displayed and note the recurring structure.

{% coach %}
Tell a bit about HTML tags and their semantic meaning.
{% endcoach %}

### More HTML

Add the following either before or after the above diary entries (again, do adjust to taste):

{% highlight erb %}
<div>
  <h1>My favourite websites</h1>
    <ul>
      <li><a href="https://railsgirls.com">Rails Girls</a></li>
      <li><a href="https://en.wikibooks.org/wiki/Ruby_Programming">Wikibooks</a></li>
      <li><a href="/">Ruby on Rails Guides</a></li>
    </ul>
  </div>
  <img src="https://railsgirls.com/images/rg-warsaw.png" />
{% endhighlight %}

This is an HTML unordered list with some list items containing anchors (links) with hypertext references (URLs) to other pages. It’s followed by a paragraph containing an image – and the image’s source is at the given URL.

{% coach %}
Explain how the Web works and talk a bit about HTML elements and attributes.
{% endcoach %}

[Here](https://github.com/krzysztofbialek/Rails-Girls-Warsaw-App)'s a link to repo with styled basic app you can use.

## Moving to Rails

### New Rails application

Open a terminal window (Command Prompt on Windows), change to the directory where your files are (using the `cd` command) and run `rails new diary` – this will take some time and end up creating a new Rails application. Run `cd diary` to change to the app’s directory.

{% coach %}
Explain how to navigate directories and run commands.
{% endcoach %}

### Running the server

Once in the `diary` directory run `rails server` and (once it finishes starting up) go to <http://localhost:3000> in your browser. You should see the ‘Welcome aboard’ page. Stop the server by pressing `ctrl-c`.

{% coach %}
Explain what has happened and what’s the output in the terminal window. If the server fails to start due to a missing JavaScript runtime, `gem install therubyracer` and uncomment the relevant line in `Gemfile`.
{% endcoach %}

### First route and view

Create the controller and the route

Run `rails generate controller welcome index` – this will generate your first controller and a route that leads to it. Start your server and go to <http://localhost:3000> to see that your application indeed does support the `/welcome/index` route.

Stop the server and run `rake routes` to see all the routes supported by your application.

{% coach %}
Explain URLs and the URL hierarchy. Explain how in Rails URLs map to ‘what happens behind the scene’.
{% endcoach %}

### Move the view to be the top of your site

Edit the `config/routes.rb` file and uncomment (remove the `#` from the front) the `root ’welcome#index’` line (this will probably be the 7th line). This will make the root of your application be the view rendered by the `Welcome#index` action. Go to <http://localhost:3000> and see that indeed the main page of your application now serves this view (rather than the ‘Welcome aboard’ page).

{% coach %}
Explain how the main page of an application is the root of the URL hierarchy and that it’s the page that people visit when they just put the host name into the browser’s address bar.
{% endcoach %}

### Move the existing HTML to the right view

Edit the `app/views/welcome/index.html.erb` file and copy the contents of the `<body>` tags from your original `index.html` file (i.e., the list of diary entries and the website links) there, replacing the two lines (with `<h1>` and `<p>`) in the view. Refresh the browser to see that the page now indeed contains the right contents.

{% coach %}
Explain that the view only contains the part between `<body>` and `</body>`, as the rest is common to the whole application and is defined elsewhere.
{% endcoach %}

## Iteration

### Repeated content

If you look at the structure of your list of links, it seems that every list item looks similar to the others – it contains a URL (where the link should take the user when clicked) and a name (what should the user see and be able to click on). Rather than writing the links as raw HTML (and potentially make a mistake with some of them) let’s abstract this a bit and iterate over a collection of URL-and-name pairs.

Replace the contents of the `<ul>` tags with the following:

{% highlight erb %}
<%
  @websites = [
    ["https://railsgirls.com", "Rails Girls"],
    ["https://en.wikibooks.org/wiki/Ruby_Programming", "Wikibooks"],
    ["https://guides.rubyonrails.org", "Ruby on Rails Guides"],
  ]
%>
<% for url, name in @websites %>
  <li><a href="<%= url %>"><%= name %></a></li>
<% end %>
{% endhighlight %}

Refresh the browser window to see whether your page still has the same links.

{% coach %}
Explain what happened – what is an array, what do `<%` and `<%=` ERb tags mean (and how they differ), how iteration works.
{% endcoach %}

Keeping code or data (like the above `@websites` array) in views is simple, but a bad practice and can bite in the long run. For starters let’s move the `@websites` array from the view to the controller. Remove it from the view and put it in `app/controllers/welcome_controller.rb` in the `index` method so it looks like this:

{% highlight ruby %}
class WelcomeController < ApplicationController
  def index
    @websites = [
      ["https://railsgirls.com", "Rails Girls"],
      ["https://en.wikibooks.org/wiki/Ruby_Programming", "Wikibooks"],
      ["https://guides.rubyonrails.org", "Ruby on Rails Guides"],
    ]
  end
end
{% endhighlight %}

Note that after refreshing your browser window nothing should change – this is because variables starting with @ (called ‘instance variables’) can be accessed by both the view and the controller.

{% coach %}
Explain the connection between the `WecomeController#index` action and the view; note and emphasise the difference between @-starting `@websites` and plain `url` or `name`.
{% endcoach %}

### Create the model

With the website links out of the hard-coded way, let’s do something with the diary entries. This time we won’t (ab)use a simple Ruby structure like an array, but a proper model that represents a given entry’s data. Let’s start with generating the model – run `rails generate model Entry title:string date:date contents:text` to create an `Entry` model that can represent a diary entry with a title, a publication date and some contents.

{% coach %}
Explain what models are and the `field:type` notation for generating them; explain the difference between `string` and `text` types if necessary.
{% endcoach %}

### Migrate the database

Run `rails db:migrate` to migrate the database so that its structure contains a table for entries.

{% coach %}
Explain what databases are (in abstract terms, as vessels for storing our application’s data and providing model structures) and why they are needed. Explain that things which are in memory won’t get persisted by default and they need to be persisted explicitly to be available on the next request.
{% endcoach %}

### Play with the model in the Rails console

Now that we have a model, we can start creating instances of that model – i.e., actual diary entries that aren’t hard-coded in the HTML view. For this, we’ll learn a new tool: the Rails console. Start it with `rails console` and, once it boots and shows: you the `>>` prompt, create a few entries:

{% highlight sh %}
>> Entry.create "title" => "Submitted a Rails Girls application", "date" => Date.new(2014, 2, 1), "contents" => "Just submitted an application to a Rails Girls workshop. Can’t wait to see whether I’ll get in!"
…
>> Entry.create "title" => "Got in!", "date" => Date.new(2014, 2, 15), "contents" => "Received an email that my application got accepted! I’ll be at a RG workshop next week!"
…
>> Entry.create "title" => "The first day starts…", "date" => Date.new(2014, 2, 22), "contents" => "Today is the first day of the Rails Girls workshop. My coach is quite strange but it seems we all have Rails installed now and can start learning."
{% endhighlight %}

Note how the console – just like `rails server` – shows you a log of what happens in the background. You can always get an array of all existing entries via `Entry.all`.

{% coach %}
Explain what’s going on. Slowly.
{% endcoach %}

## Viewing the persisted contents

### Add the model instances to the existing view

Edit the `WelcomeController#index` action (in the `app/controllers/welcome_controller.rb` file) and add the following either before or after the lines containing `@websites` definition:

{% highlight ruby %}
@entries = Entry.all
{% endhighlight %}

Edit the `app/views/welcome/index.html.erb` view and replace the lines with the diary entries with the following:

{% highlight erb %}
<% for entry in @entries %>
  <h2><%= entry.title %></h2>
    <p><%= entry.date %></p>
    <p><%= entry.contents %></p>
<% end %>
{% endhighlight %}

{% coach %}
Discuss what happened; discuss what’s the order of the entries and how they can be reordered (say, by reverse date) and where it should happen.
{% endcoach %}

### Create a controller for diary entries

Now that we have a model we need to create a controller for handling actions related to the instances of the model (creating new entries, showing, editing and deleting existing ones). Run `rails generate controller Entries` – this should generate the `EntriesController` class. Check `rake routes` – notice that the controller isn’t enough, we still need to point URLs to the controller’s actions.

Edit `config/routes.rb` and add a `resources "entries"` line somewhere inside the `Diary::Application.routes.draw` block. Run `rake routes` again: notice how now your application has all kinds of new routes.

{% coach %}
Explain how Rails’ route resources work and how they make URLs spring to existence and map to controller actions by default.
{% endcoach %}

### A view of all the entries

As can be seen in the `rake routes` output, the URLs are wired to their relative controller actions. Let’s see what’s missing – visit <http://localhost:3000/entries> in your browser. Uh-oh, it seems like the ‘index’ action is missing – let’s add it – open `app/controllers/entries_controller.rb` and add the below empty method inside the class definition:

{% highlight ruby %}
def index
end
{% endhighlight %}

Now refresh the browser – we no longer have an ‘unknown action’ problem, we now have a ‘template is missing’ problem. Save an empty file as `app/views/entries/index.html.erb` (note it’s just like the `index.html.erb` file in the ‘welcome’ directory before, but this time it’s in the ‘entries’ directory) and refresh the browser again – it should display an empty page. This is good, as our view is quite empty at the moment.

{% coach %}
Explain how actions render the related views by default.
{% endcoach %}

Now go to the `app/controllers/welcome_controller.rb` file and find the `WelcomeController#index` method (the one that starts with `def index`). Find the line that sets the `@entries` variable (it should start with `@entries =`) and copy it to `EntriesController#index` (so to the `index` method of the `EntriesController`, which can be found in `app/controllers/entries_controller.rb`). Similarly, go to the `app/views/welcome/index.html.erb` view and copy the `@entries.each` block (all of the indented lines up to and including the matching `end`) to the `app/views/entries/index.html.erb` view. Refresh the browser: it should now show the list of all your diary entries.

{% coach %}
Explain that even though this might look like little to no progress, there is a significant change: we’re no longer operating in the context of the main page of our app, but rather a list of diary entries only (without the links to other websites, for example).
{% endcoach %}

### A view of a single entry

Note how, when you run `rake routes`, the output says that the `/entries/:id(.:format)` pattern maps to the `entries#show` controller action. Go to <http://localhost:3000/entries/1> – the URL for your first diary entry; notice how we’re, again, missing an action of the `EntriesController`. Add that (empty for now) action, then refresh the browser and add the (likewise, empty) missing view.

{% coach %}
Guide through adding the missing action and view if needed; make sure the process (all the way from deciphering the right `rake routes` line) is well understood.
{% endcoach %}

Now, let’s figure out how to interpret the `1` from the end of the URL to display the right entry. Make the `EntriesController#show` action look like this:

{% highlight ruby %}
def show
  @entry = Entry.find(params["id"])
end
{% endhighlight %}

This line means ‘take the `id` parameter and use it in the `Entry.find` method to find the right entry’. Now edit the `app/views/entries/show.html.erb` view and put there the following:

{% highlight erb %}
<h2><%= @entry.title %></h2>
  <p><%= @entry.date %></p>
  <p><%= @entry.contents %></p>
{% endhighlight %}

Visit <http://localhost:3000/entries/1> and compare it with <http://localhost:3000/entries/2> to see how using `params[’id’]` means that different diary entries get displayed.

{% coach %}
Explain that the `:id` part of the URL template from `rake routes` is made into a key for the `params` hash; discuss what else can be found in the `params` hash.
{% endcoach %}

### Linking entries

Run `rake routes` again; notice how the row for the `entries#show` action starts with `entry` in the ‘prefix’ column. Go to the `app/views/entries/index.html.erb` view and change the line responsible for displaying the title to the below:

{% highlight erb %}
<h2><%= link_to(entry.title, entry_path(entry)) %></h2>
{% endhighlight %}

Note how we use the `link_to` method that takes two parameters, the text to display (`entry.title`) and the path to link to. Check the source of the page to see what is the path for subsequent titles. Note how the path is created by calling the `entry_path` method with `entry` as its argument.

{% coach %}
Remind how the HTML for links looks like. Explain the relation between `entry_path` and the `entry` prefix from `rake routes`. Explain why the `entry_path` method needs the `entry` argument. Explain what the `entry_url` method does (and how it differs from the `entry_path`  method) if you want to.
{% endcoach %}

Now let’s try to get back from an entry screen to the index of all entries: edit the `app/views/entries/show.html.erb` template and add a link to the entries index, like this:

{% highlight erb %}
<p><%= link_to("Back to all entries", entries_path) %></p>
{% endhighlight %}

Note, again, how the `entries` prefix from `rake routes` is used to construct the `entries_path` method name. Note how this method does not need a parameter.

## Creating entries via the UI

### Adding the ‘new entry’ form

Now that we have a way to display a list of all entries and a single entry, let’s add a way to create new diary entries. Run `rake routes` and try to figure out which URL (and action) is responsible for new entry creation.

Go to the index of all entries and add a link for creating new entry:

{% highlight erb %}
<%= link_to("New entry", new_entry_path) %>
{% endhighlight %}

Click the link – and add the missing action and view.

{% coach %}
Make sure this process is well understood by now.
{% endcoach %}

Edit the `app/views/entries/new.html.erb` view and paste in the below:

{% highlight erb %}
<%= form_for(Entry.new) do |form| %>
  <p><%= form.label("title") %></p>
  <p><%= form.text_field("title") %></p>
  <p><%= form.label("contents") %></p>
  <p><%= form.text_area("contents") %></p>
  <p><%= form.submit %></p>
<% end %>
<p><%= link_to("Back to all entries", entries_path) %></p>
{% endhighlight %}

**Note:** we can skip labels for now

{% coach %}
Show how the HTML produced by the `form_for` helper looks like and try to explain how it works.
{% endcoach %}

### Handling the ‘new entry’ form

Refresh the browser and try adding a new entry – you should see the well-known-by-now ‘unknown action’ error. Add the action to the `EntriesController`, but for starters let’s display what the action receives:

{% highlight ruby %}
def create
  render(:text => params.inspect)
end
{% endhighlight %}

Refresh the browser and inspect what exactly the action gets as its params.

{% coach %}
Explain how filling a text field and a text area and submitting the form ends up with all the params being POSTed to the controller’s action. Explain what .inspect does.
{% endcoach %}

### Creating and persisting the new entry

Edit the `create` action and make it look like this:

{% highlight ruby %}
def create
  entry_params = params["entry"]
  entry = Entry.create(entry_params)
  redirect_to(entry_path(entry))
end
{% endhighlight %}

Note how we try to get the parameters of the new entry (its title and contents) from the `params` hash and then create a new entry from them, just like in the console. Try submitting the form again – notice that we’re still not there yet, as we get a `ActiveModel::ForbiddenAttributesError`.

- Note: we can skip strong_parameters in the beginning, keeping the application not secure from parameter injection.
- config.action_controller.permit_all_parameters = true
- ^^ yeah, but it will be removed soon.
- maybe not before workshops ;)

This error is because of security measures – it’s relatively simple to POST whatever parameters a user wants to, and Rails protects us from a rogue user that would want to set parameters that they’re not supposed to set (like ‘id’). We need to declare which parameters can be set by the user; change the first line of the `create` action to the below:

{% highlight ruby %}
entry_params = params["entry"].permit("title", "contents")
{% endhighlight %}

Now try submitting the form again – this time it should work and you should get redirected to the newly-created entry.

{% coach %}
Make sure the plucking of the new entry’s parameters from `params` is well understood and that it’s accepted that certain fields need to be permitted explicitly.
Editing via the UI
{% endcoach %}

### Adding the ‘edit entry’ form

Now that we can view and create entries, let’s also add the option to edit them. Run `rake routes` and try to guess which route is responsible for editing an entry.

{% coach %}
Make sure this is well understood by now.
{% endcoach %}

Edit the `app/views/entries/show.html.erb` view and add the below line somewhere:

{% highlight erb %}
<p><%= link_to("Edit this entry", edit_entry_path(@entry)) %></p>
{% endhighlight %}

Refresh a given entry’s view and click the link. Add the missing action and an empty view.

{% coach %}
Again, make sure this is well understood.
{% endcoach %}

Let’s first make sure our `edit` action exposes the right entry to the view. Make sure the `edit` action looks just like the `show` action – i.e., it grabs the right entry based on the id from the URL:

{% highlight ruby %}
def edit
  @entry = Entry.find(params["id"])
end
{% endhighlight %}

Now copy the contents of the `app/views/entries/new.html.erb` view to the `app/views/entries/edit.html.erb` view, but change the first line so that it’s a form for this particular entry – and, optionally, add a link back to this entry’s show screen:

{% highlight erb %}
<%= form_for(@entry) do |form| %>
  <p><%= form.label("title") %></p>
  <p><%= form.text_field("title") %></p>
  <p><%= form.label("contents") %></p>
  <p><%= form.text_area("contents") %></p>
  <p><%= form.submit %></p>
<% end %>
<p><%= link_to("Back to this entry", entry_path(@entry)) %></p>
<p><%= link_to("Back to all entries", entries_path) %></p>
{% endhighlight %}

{% coach %}
Make sure all of this is well understood.
{% endcoach %}

Now try to submit the form – which action is still missing? Create it in the controller:

{% highlight ruby %}
def update
  entry_params = params["entry"].permit("title", "contents")
  entry = Entry.find(params["id"])
  entry.update(entry_params)
  redirect_to(entry_path(entry))
end
{% endhighlight %}

Check whether this all works and whether you can now edit the entries.

{% coach %}
Make sure the `update` action’s contents are well understood – from permitting params through finding entries to redirecting to the right path.
{% endcoach %}

## Further ideas

Play with your application! Here are some further ideas you might want to add:

- extract form to a partial
- links for editing an entry straight from the index of entries,
- a way to delete an entry,
- a way to edit entry dates,
- a model for tracking website URLs and names (the list on the main page),
- setting entry dates to the future and not displaying future entries in the index until their day comes,
- automatic embedding of video URLs,
- support for different entry authors,
- support for different categories of entries,
- upload and display of images.


================================================
FILE: _pages/github.md
================================================
---
layout: main_guide
title: Push your app to GitHub
description: "Share your code with others by pushing your app's code to GitHub."
permalink: github
---

# Push your app to GitHub

*Originally created by Alyson La, [@realalysonla](https://www.twitter.com/realalysonla)*

{% include main-guide-intro.html %}

Git is a tool with which it's possible to save your app's source code, view changes over time, share code online and collaborate with others.

{% coach %}
Talk a little about Git, version control, collaborating with others using Git, GitHub, deployment techniques using Git and Open Source.
{% endcoach %}

## Installing Git

Before working with Git, we first need to check if Git is already installed. In the terminal type the following command:

{% highlight sh %}
git --version
{% endhighlight %}

The output should mention Git version 1.8 or higher. If it is not installed (indicated by a "command not found" or similar error), or the version is lower than 1.8, please install or upgrade Git.

<div class="os-specific">
  <div class="mac">
<p>Run this command in the Terminal to install or upgrade Git on macOS.</p>
{% highlight sh %}
brew install git
{% endhighlight %}
  </div>
  <div class="nix">
<p>Follow the <a href="https://git-scm.com/download/linux">instructions for your Operating System</a> in the Git documentation.</p>
  </div>
  <div class="win">
<p>Please install Git by going to the <a href="https://git-scm.com/download/win">Git website</a>, download the Git installer for Windows and running the downloaded installer.</p>
  </div>
</div>

After installing or upgrading, run the `git --version` command again to make sure you are using a more recent version.

## Configuring Git

Once we're sure Git is installed, we can set up our local profile in Git. This profile will be used to describe who made the changes to files we'll store in Git. You can see who made which change and when.

Change "your name" and "your email" with your name and your email address. You can also use a nickname or an alias if you don't want to use your real name and email address. Be aware: the name and email address you configure here will be visible to others!

{% highlight sh %}
git config --global user.name "your-name"
git config --global user.email "your-email"
{% endhighlight %}

To check if a profile is already set up in Git, you can run this command, and look for the `user.name` and `user.email` values in the output:

{% highlight sh %}
git config --list
{% endhighlight %}

## Saving work in Git

Open the Terminal app, navigate to your _railsgirls_ app directory and run the following command. This will list out all the changed files in your app directory, which should be all the files for your app.

{% highlight sh %}
git status
{% endhighlight %}

We want to save all these files in Git so they can be pushed to the GitHub repository you just created. By running the following command you will add all those files staging area in Git, ready to be saved (committed).

{% highlight sh %}
git add .
{% endhighlight %}

The `git commit` command shown below will save the staged files in Git, along with the message "First commit".

{% highlight sh %}
git commit -m "First commit"
{% endhighlight %}

(The `-m` in the above command stands for "message".)

## Create a GitHub account

GitHub is a free, online, code-sharing platform. It is a _hub_ for source code saved in _Git_. We will use this to save and share our app's source code.

Visit the [GitHub website](https://github.com) and create an account or login if you already have an account at Github.

## Securely sharing your code with GitHub

The easiest method for managing authentication is creating a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) that will have matching parts stored on your computer and also on the GitHub site.

Because you are trying to get the code on your computer into your account on the GitHub website, you'll need to connect via the internet. GitHub offers connections over HTTPS and SSH. Using a Personal Access Token (PAT) requires that you use an HTTPS connection. This will be important in the next section, when you'll create your PAT. 

## Push your app to GitHub using the command line (part 1)

Now that you have a GitHub account, you can push (Git terminology for _upload_) your saved work to GitHub and share it with others.

Once signed in to GitHub, click on the plus icon (`+`) in the top right corner of the navigation bar. In the dropdown, choose "New repository".
Having trouble finding the right link? Visit this [new repository page](https://github.com/new) directly.

On the "Create a new repository" page, enter a repository name (like "railsgirls"), choose "public" for the repository's visibility and click the "Create repository" button. Leave the rest of the form untouched.

The next page will list the repository URL we will need to tell Git where to push your app's source code to. 

Be certain you are viewing the instructions for HTTPS, so that it will work with the PAT. In the top "Quick setup" section, click on the "HTTPS" button if it is not already selected, and see that all the instructions change the links to start with `https`.

You should use the "push an existing repository from the command line" instructions. Within that section, find the line that starts with `git remote add origin`. Copy the entire line and paste it into the Terminal app. Then press enter.

This step creates a Git _remote_, a _connection_, named "origin" pointing to the GitHub repository you just created in the local repository.

## Create the Personal Access Token

Next you need to [create the PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-personal-access-token-classic). 

You can access your GitHub personal access tokens here: <https://github.com/settings/tokens>. Or, when you are logged in to GitHub, you can start on any page and click on your avatar in the top right. Then click "Settings", then "Developer settings", then "Personal access tokens", then "Tokens (classic)".

Once you are on the "Personal access tokens (classic)" page, click on the "Generate new token" dropdown menu and select "Generate new token (classic)". If you have set up two-factor authentication in your GitHub account, you will need to 2FA authenticate now. 

When you can see the "New personal access token (classic)" form, use the "Note" to describe this repo (e.g. "RailsGirls") and then select an expiration date. (If you plan to use this project beyond the expiration date, you'll need to repeat these steps when the PAT expires.)

Then, for scopes, select the top "repo" checkbox, that gives the PAT "Full control of private repositories".

Click "Generate token" at the bottom of the page.

On the next page you'll see your PAT. This is the only time you'll have access to it, so don't click away from this page until you have completed the _push_ step in the next section. 

Copy and save the PAT token, ideally in a secure password manager. Be careful not to copy any spaces before or after the token -- you can use the two-squares copy button at the end of the token to be certain. You can keep the browser window open until you've completed the next step.

## Push your app to GitHub using the command line (part 2)

Now we want to _push_ the local changes in the Git repository to the repository on GitHub with the following command in your terminal.

{% highlight sh %}
git push -u origin master
{% endhighlight %}

_Your app's branch name may be different, like `main`. Change the "master" argument to the branch name listed in `git branch`. Your current branch is indicated with the `*` symbol at the start of the line._

When the authentication prompt appears in your terminal, use your PAT as the password, example below. Note that when you paste your PAT in the password, it will not show. Don't paste again, or you will be entering the token twice.

{% highlight sh %}
Username: <your GitHub username>
Password: <paste in your personal access token>
{% endhighlight %}

You may need your PAT every time you want to push your code, or you can save the PAT on your computer. This process varies per operating system, so your coach can help you with this process if you plan to keep pushing your code to GitHub.

{% coach %}
Please help with caching the PAT, if the participants wants to. Find the latest guide for their operating system, or check out this guide for [storing the PAT on different Operating Systems](https://mgimond.github.io/Colby-summer-git-workshop-2021/authenticating-with-github.html#saving-tokens-in-windows).
{% endcoach %}

Congratulations your app is on GitHub! Refresh the page in the Browser and you should see a bunch of files there now.

## Saving more changes in Git

If you want to continue making changes and pushing them to GitHub you'll need to use the following three commands.

Add changes you want to save in Git to the _staging area_:

{% highlight sh %}
git add .
{% endhighlight %}

Save the changes with a commit message:

{% highlight sh %}
git commit -m "Type your commit message here"
{% endhighlight %}

Use a descriptive message so you can find back what you changed in which commit and why.

{% coach %}
Talk about what makes a good commit message (active, descriptive and short).
{% endcoach %}

And push the changes to GitHub:

{% highlight sh %}
git push origin master
{% endhighlight %}

_Your app's branch name may be different, like `main`. Change the "master" argument to the branch name listed in `git branch`. Your current branch is indicated with the `*` symbol at the start of the line._

## What's next?

### Learn more about Git

* Use a [Git Cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/) for frequently used commands ([also available as a PDF](https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf)).
* Look up more Git commands in [the Git documentation](https://git-scm.com/docs).
* Try out a Graphical User Interface (GUI) if you prefer a more visual experience for using Git. Try out an app like [GitHub Desktop](https://desktop.github.com/).
* In the future, as you'll work with more people on a project, you'll start working with branches and pull requests more often.

### Be a part of the Open Source community

* Follow your fellow Rails Girls & coaches on GitHub and see what they're working on.
* Star or watch their projects.
* [Fork a repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo) (a "repo"), then clone and push changes to your fork. Share the changes with the originator by sending them a [pull request](https://help.github.com/articles/using-pull-requests)!
* Create an issue on a project when you find a bug.
* Explore other Open Source projects - search by programming language or keyword.


================================================
FILE: _pages/gravatar.md
================================================
---
layout: guide
title: Adding Gravatar to you app
description: "Load user avatars using the Gravatar service. That way your users don't need to upload an avatar to your app."
permalink: gravatar
---

# Adding Gravatar to your App

*Created by Catherine Jones*

Gravatar is a service for hosting user avatars. If you sign up with Gravatar you don't need to upload your picture for a lot of services, as it automatically detects it from Gravatar.

## Important

This guide assumes that you have already built a Rails Girls app by following this [app development guide](/app) and added authentication using [Devise](/devise).

You need to have an e-mail address registered with Gravatar for this to work. If you do not already have one you can go to [gravatar.com](https://gravatar.com/).

## *1.* Add the Gravtastic gem

{% coach %}
At time of writing the [Gravtastic Ruby gem](https://rubygems.org/gems/gravtastic) is archived and no longer maintained. If you know of a maintained alternatives, please update the guide.
{% endcoach %}

Open up your gemfile and under your `devise` gem add

{% highlight ruby %}
gem 'gravtastic'
{% endhighlight %}

In the terminal run

{% highlight sh %}
bundle install
{% endhighlight %}

This will install the gravtastic gem. Then remember to restart your rails server.

## *2.* Set up Gravatar in your app

Open `app/models/user.rb`, and add these lines

{% highlight ruby %}
include Gravtastic
gravtastic
{% endhighlight %}

right after the first line.

## *3.* Configure Gravatar

Open `app/views/layouts/application.html.erb` and in the

{% highlight erb %}
<% if user_signed_in? %>
{% endhighlight %}

section but before the

{% highlight erb %}
<% else %>
{% endhighlight %}

add

{% highlight erb %}
<%= image_tag current_user.gravatar_url, :class => "gravatar" %>
{% endhighlight %}

And, put the following code to the bottom of `app/assets/stylesheets/application.css`:

{% highlight css %}
.gravatar {
  height: 30px;
  width: auto;
}
{% endhighlight %}

Now open you app in your browser and login with an e-mail address that is associated with a Gravatar. You should be able to see your Gravatar.


================================================
FILE: _pages/guide-to-the-guide.md
================================================
---
layout: guide
title: The Guide to the Guide
descriptive: "The guide for coaches to follow along with the guides the workshop participants are following."
permalink: guide-to-the-guide
---

# Your guide to the Rails Girls Guide!

*Originally created by H Salmon to accompany the [app guide](/app).*

This guide is an accompaniment to the first [main numbered Rails Girls guides](/#guides) you will be using to build your first Rails application. Its purpose is to provide background information about the structure of a Rails application, Rails terminology and commands, so you can understand what is happening when you are implementing the code in the Rails Girls Guide. We hope that this guide will provide you with a way to retain what you learn over the course of this workshop, and to maintain your interest in Rails development. Welcome!

- [Creating the application](#1_create_the_application)
  Commands you need to know
- [Creating Idea scaffold](#2_create_idea_scaffold)
  Scaffolding, models, migrations
- [Finetuning the routes](#3_finetune_the_routes)
  Routes, HTTP Methods: GET, POST, PUT and DELETE
- [Designing](#4_design)
  The design layers ( HTML, CSS, ERB)
  MVC Architecture
- [Adding picture uploads](#5_add_picture_uploads)
  Libraries, gems and open-source

<a id="1_create_the_application"></a>
## *1.* Create the application

In the [build your first app guide](/app) we'll create our first Rails app. We'll start with these commands:

- `mkdir projects` - makes a *directory* (folder) called “projects” in the folder you are currently in, most likely your home folder.
    - `mkdir` = **m**a**k**e **dir**ectory.
- `cd projects` - navigates to the “projects” folder you just created.
    - `cd` = **c**hange **d**irectory.
- `rails new railsgirls` - creates a new Ruby on Rails application called **railsgirls** containing various auto-generated folders, in your *working directory* (the folder you are working in at the moment).
- `cd railsgirls` - navigates to the “railsgirls” folder.
- `rails server` - starts a local web server on your computer. This web server is accessed through the web address <http://localhost:3000>.
  - "Localhost" refers specifically to your computer (considered the “local host”), from which a server is being launched. Localhost provides a way for developers to see their application in a browser and test the functionality while it is still in development.

<a id="2_create_idea_scaffold"></a>
## *2.* Create Idea scaffold

In the [build your first app guide](/app) we'll quickly make some Rails app code using scaffolding.

### What is Rails scaffolding?

Every web application consists of many different concepts or resources (such as “users”, “ideas”, “posts”, “comments”, etc.).
Rails scaffolding is a command (`rails generate scaffold`) for introducing a new resource into your application. It generates all of the code files necessary for representing and interacting with this resource.

### What is a model?

In Rails, a model represents a definition of a resource in your application, and how it should interact with other parts of the application. Depending on the nature of the website, these resources could be users, posts, groups etc. When a model is generated, a corresponding *database table* is created. This database table contains information that represents specified attributes of the model, e.g. for a User model, there might be a ‘name’ column and an ‘email’ column, and there will be rows for each subsequent user created. In the application you are creating, these resources are ideas and the model is ‘Idea’.

{% highlight rb %}
rails generate scaffold idea name:string description:text picture:string
{% endhighlight %}

In order to create our idea model, we use the `scaffold` command which includes an argument with the singular version of the model name (`idea`), and an argument with parameters (specifications) for the model’s attributes. This means that the `idea` model corresponds to a table in the database with columns for the attributes specified in the command: `name`, `description` and `picture`. The `scaffold` command also auto-generates an `id` attribute, referred to as the `primary key`, which is used to establish relationships between database tables.

- `rails generate scaffold` - this calls the scaffold command.
- `idea` - this tells the scaffold command what we want to call our model.
- `name:string description:text picture:string` - provides a list of attributes we want our model (and the database table that goes with it) to have. The `string` and `text` parts of the argument determine the nature of each attribute, i.e. each description needs to be ‘text’, and not, for example, an ‘integer’ (or any other type of information).

### The ideas table

<table class="table table-hover table-bordered">
	<thead>
		<tr>
			<th>id</th>
			<th>name</th>
			<th>description</th>
			<th>picture</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>1</td>
			<td>“Money-spinner”</td>
			<td>“Open a moveable shop!”</td>
			<td>“GreatIdea.jpg”</td>
		</tr>
		<tr>
			<td>2</td>
			<td>“Champagne For Breakfast!”</td>
			<td>“We should do this every Friday!”</td>
			<td>“Champagne.jpg”</td>
		</tr>
		<tr>
			<td>3</td>
			<td>...</td>
			<td>...</td>
			<td>...</td>
		</tr>
	</tbody>
</table>

### Naming conventions

#### Active Record
In Rails, the default system for communicating with an application’s database is called *Active Record*, which provides various methods for creating, saving, and finding data. To retrieve information from the database, *Active Record* establishes relationships between different parts of the application using naming conventions:

- Table names have all lowercase letters and underscores between words, e.g. “ideas”, “invoice\_items”
- The model is named using the convention of unbroken MixedCase and is always the singular of the table name, e.g. if the table name is “invoice\_items”, the model name would be “InvoiceItem”. So, in this case our table name is "ideas" and our model is "Idea".

#### Model attributes and types

As we’ve already discussed, a model can have attributes (properties) represented by columns in the corresponding database table. To be supported by the Active Record system, these attributes must conform to a list of appropriate types:

- `:binary` - stores data such as images, audio files or movies
- `:boolean` - stores true or false values (such as whether a particular user is an administrator of an application or not)
- `:date` - stores only a date (year, month, day)
- `:datetime` - stores both a date and a time
- `:decimal` - stores decimal numbers with precision that varies according to your specifications
- `:float` - stores decimal points with fixed precision i.e. you can’t specify the precision (`:decimal` is better for mathematical operations in which precision is required, but `:float` is processed faster and is better in situations where speed is required and accuracy is secondary)
- `:integer` - stores whole numbers
- `:primary_key` - the primary key of a table is assumed to be the id
- `:string` - stores 255 characters of text information, i.e. is used for short text fields (names, emails etc)
- `:text` - stores text information with no character limit (used for comments, blog posts etc)
- `:time` - stores only a time
- `:timestamp` - stores both a time and date. `:timestamp` is different from `:datetime` and serves a different purpose, but there’s no need to go into that here

### What are migrations and why do you need them?

Migrations change the state of the database. When you run the `scaffold` command, a migration file containing instructions for the database table relevant to your command is added to the `db/migrate` folder of your application. For example, when you ran the `rails generate scaffold` command, a migration containing instructions for our ideas table was created. There are other commands that create migrations such as the `rails generate model` command and the `rails generate migration` command.

The `rails db:migrate` command updates the database according to the specifications in the migration file. This command, known as “migrating up”, ensures that your idea model is added to the database. Migrations can also be undone (“migrating down”) using the command `rails db:rollback`.

<a id="3_finetune_the_routes"></a>
## *3.* Finetune the routes

In the [build your first app guide](/app) replace the Rails splash page with a redirect to our ideas scaffolding.

In a functional Rails application, there is an inbuilt system in place for translating incoming requests from the browser in order to return the intended response. This system is called *routing*. Requests from the browser are interpreted as specific HTTP methods. HTTP (Hypertext Transfer Protocol) is the protocol that defines how information (usually webpages or webpage components composed of text with hyperlinks - ‘hypertext’), is formatted and transmitted across the internet. There are four primary HTTP methods, each of which is a request to perform an operation on a specific resource (e.g. users, posts); GET, POST, PUT and DELETE. Rails’ inbuilt routing system automatically generates routes for each resource that map to specific actions (index, show, new, edit, create, update, delete) defined in the controller. So, for each of our models, there are seven related actions defined in the associated controller, `ideas_controller.rb`. These actions specify the appropriate response (a ‘method’) which is most likely to render the corresponding view, e.g. `ideas/index.html.erb`.


<table class="table table-bordered table-hover">
	<thead>
		<tr>
			<td>HTTP Method</td>
			<td>Path</td>
			<td>Action</td>
			<td>used for</td>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>GET</td>
			<td>/ideas</td>
			<td>index</td>
			<td>displaying a list of all ideas</td>
		</tr>
		<tr>
			<td>GET</td>
			<td>/ideas/new</td>
			<td>new</td>
			<td>returning an HTML form for creating a new idea</td>
		</tr>
		<tr>
			<td>POST</td>
			<td>/ideas</td>
			<td>create</td>
			<td>creating a new idea</td>
		</tr>
		<tr>
			<td>GET</td>
			<td>/photos/:id</td>
			<td>show</td>
			<td>displaying a specific photo</td>
		</tr>
		<tr>
			<td>GET</td>
			<td>/photos/:id/edit</td>
			<td>edit</td>
			<td>returning an HTML form for editing a specific photo</td>
		</tr>
		<tr>
			<td>PUT</td>
			<td>/photos/:id</td>
			<td>update</td>
			<td>updating a specific photo</td>
		</tr>
		<tr>
			<td>DELETE</td>
			<td>/photos/:id</td>
			<td>destroy</td>
			<td>deleting a specific photo</td>
		</tr>
	</tbody>
</table>


If you look in your `ideas_controller.rb` you can see these actions and the associated behaviour, and the HTTP method that corresponds with each action:

{% highlight rb %}
def show
    @idea = Idea.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @idea }
    end
  end

  # GET /ideas/new
  # GET /ideas/new.json
{% endhighlight %}

`show` - the controller action

{% highlight rb %}
respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @idea }
{% endhighlight %}

(This code is difficult to dissect with much clarity at this stage but if you persist with Rails you will get a better understanding as time progresses.)

In the above definition of the show action, Rails is using a `respond_to` helper method, which tells Rails to execute the subsequent *block* of code (the code enclosed by the `do...end` syntax). This code contains two different formatting options depending on the nature of the request. If the browser requests HTML then the HTML code contained in the view that corresponds with this controller action (`show.html.erb`) is rendered. If JSON is requested then the view is bypassed and limited information is provided.

`GET` - this is a comment to let us know which HTTP method is being executed.

So, URL requests, translated into HTTP methods, are mapped to controller actions which tell Rails to return a view.

When we insert the code `root :to => redirect("/ideas")` into our `config.rb`, it tells Rails to make the default root of our application <http://localhost:3000/ideas> (note Localhost is being used as the domain because our application is still in development, when you launch your application this domain will be different). This URL contains a path (`/ideas`) which, by default, maps the URL to the ‘index’ action of our ideas controller and renders the associated view; `index.html.erb`. The code `rm public/index.html` removes (`rm`) the `public/index.html` file, containing the “Welcome Aboard” code, which was the previous default root for our application.

<a id="4_design"></a>
## *4.* Design

In the [Style your app using HTML and CSS guide](/html-and-css) we'll add HTML and CSS to the app to customize it.

In a Ruby on Rails application, the user interface (what someone visiting the website will see), is often written in HTML with Embedded Ruby (ERB) code. This code is contained in a specific directory called ‘views’, located in the `app` folder of your Rails application directory.

### HTML
HTML, which stands for HyperText Markup Language, is the primary language for creating web pages and other information that can be displayed in a web browser. HTML is written using tags, angle brackets which tend to come in pairs (a “start tag” and an “end tag”), enclosing text-based content. In paired tags, the end tag also has a slash after the opening angle bracket, to distinguish it from the start tag. A paragraph (represented in HTML by the letter ‘p’) would use a start tag like this: `<p>` and an end tag like this: `</p>`, to enclose the text intended for display. Unpaired tags that are opened but don’t need to be closed (e.g. `<br>`, which defines a single line break) are known as “empty elements”. The web browser uses HTML tags to interpret how the contents will be displayed.

### ERB: Embedded Ruby
ERB is a system supplied by Ruby that allows you to insert pure Ruby code into files written in other languages, such as Javascript or HTML. The Ruby code is contained within specific angle brackets (`<%` and `%>`) which instruct the system to execute the contents. If an `=` sign accompanies the angle brackets, (`<%=` and %`>`) then the contents are executed and rendered on the page.

For example, if you had 25 active ideas in your application, the code:
`There are currently <%= Idea.count %> active ideas`
would render as:
> There are currently 25 active ideas

### MVC Architecture
In a standard Rails application (like you one you have generated), the `app/` folder of your application starts out with three folders (or directories): ‘models’ (which we have already discussed), ‘controllers’ and ‘views’. The relationship between these directories is the foundation (known as MVC Architecture) of the application, and of Rails development.

When you ran the `rails generate scaffold` command, in addition to creating the idea model, you also created an accompanying ideas controller (`ideas_controller.rb`), located in the controllers folder, and an ideas views folder containing several files that you will use to create a dynamic application.

When attempting to display a Rails website, a web browser sends a request via the server which eventually hits the Rails *controller*. *Controllers* act as mediators between the *views* and the *models*. When the *controller* receives the information, it communicates with a *model* representing a resource of the application (in our case, an “idea”) which in turn communicates with the database. Upon retrieving the required information from the *model*, the *controller* renders the *view* which returns the complete web page to the browser as HTML.

### CSS and layouts
CSS (Cascading Style Sheets) is a language used to describe the formatting of pages written in a ‘markup language’, i.e. a language for processing, defining and presenting text with a prescribed formatting code e.g. tags, that distinguish it from plain text. The most common application of CSS is in conjunction with HTML.

For each Rails application there is a default layout file called `application.html.erb`, located in the layouts folder of your views directory. With this file you can create a default format for all of the pages in your application.

{% highlight html %}
<link rel="stylesheet" href="https://railsgirls.com/assets/bootstrap.css">
{% endhighlight %}

In the above code, the `link rel` (link relation) is defining the nature of the URL that the `href` (hypertext reference) attribute is requesting content from. This argument indicates that the external source requested is a stylesheet and the web browser will need to fetch this file to render the page properly.

{% highlight erb %}
<%= stylesheet_link_tag "application" %>
{% endhighlight %}

This code returns a stylesheet link tag for the source, in this case “application”, i.e. `application.css`. This means that the styling you implemented in application.css will be applied to the various pages of your application.


{% highlight erb %}
<div class="container">
  <%= yield %>
</div>
{% endhighlight %}

In this code:

- The HTML `div` tag divides the code into parts.
- The *container class* adds additional styling to everything inside the div tags
- The `<%= yield %>` argument is responsible for inserting the unique content from each page into the container `div`. This means that in your application the overall layout can be consistent even though the content will differ from page to page.

<a id="5_add_picture_uploads"></a>
## *5.* Add picture uploads

In the [Add picture uploads](/uploads) we'll add a way to uploads pictures to ideas.

### Libraries
Many programming languages, including Ruby, use a wide range of libraries. In Ruby’s case, most of these libraries are released in the form of self-contained packages called *gems*, which contain all the information required to install and implement them. These gems are contained in your application’s `Gemfile` and if you look in this file you’ll notice that when you created your first Rails application it came with several gems that ensure your application functions correctly.

Gems help simplify and prevent repetition in a developer’s code, in keeping with the DRY (Don’t Repeat Yourself) principle of software development. Gems may solve specific problems, add specific functionality, or address specific requirements, meaning that should another developer encounter a similar scenario, instead of writing new code, they can install a gem containing pre-written code. For example, “CarrierWave”, the gem you are adding to your gemfile is designed to make it easy to upload files to your application.

“Bundler” is the software Ruby uses to track and manage gems. The `bundle install` command runs Bundler and installs the gems specified in your Gemfile. You’ll notice the code `source "https://rubygems.org"` at the top of your Gemfile. Whenever you add a gem to your gemfile and run the `bundle install` command, this code tells your application to fetch the gem from <https://rubygems.org>. “RubyGems” is a Ruby-specific packaging system, the purpose of which is to simplify the creation, sharing and installation of gems.

### Open-source software

Both the Rails framework and the Ruby language are examples of open-source software. Open-source software is released under a licence which ensures universal access; anyone has the right to change, study and distribute the software. Making the source code accessible enables the establishment of a diverse, reflexive, collaborative and consequently ever-evolving interactive community of programmers who all benefit from each others’ developments.

### More HTML

The file `app/views/ideas/_form.html.erb` contains HTML code that determines the look and feel of the form used for editing and creating ideas (the `edit.html.erb` and `new.html.erb` views). A partial is a snippet of HTML and Ruby code that can be reused in multiple locations. The form for editing existing ideas and the form for creating new ideas will look pretty much the same, so it makes sense to have one form for both files to use. If you look in these files you’ll notice that they have a customised heading (e.g. `<h1>Editing idea</h1>`) and then they simply say `<%= render "form" %>` which tells Rails to render the partial `_form.html.erb`.

If you take a look in the `_form.html.erb` file, you will see the code `form_for` in the first line of code. This is a block used to create an HTML form. Using this block, we can access methods to put different input fields in the form.

The code we are implementing, `<%= f.file_field :picture %>`, tells Rails to create a file input on the form and map the submitted information to the ‘picture’ attribute of an ‘idea’ in our ideas database table. We changed the code from `<%= f.text_field :picture %>` to `<%= f.file_field :picture %>` because `file_field` makes it easier for the user to select the image they wish to upload.

In the code `<%= @idea.picture %>`, `@idea` is known as an *instance variable*. Instance variables are prefixed with an @ symbol and are defined in the controller action that corresponds with the view in which they are referenced. For the purposes of the code we are implementing, `@idea` is defined in the ‘show’ action of the `Ideas` controller, with the code `@idea = Idea.find(params[:id])`. This makes it available for us to use in the view `show.html.erb`. It could be defined differently in different controller actions (e.g. index or new). The code `@idea = Idea.find(params[:id])` uses the Rails `find` method to retrieve specific ideas from the database.

The code that follows the `@idea` variable (`.picture`) tells Rails to access the ‘picture’ attribute of our resource (idea). By replacing the code  `<%= @idea.picture %>` with `<%= image_tag(@idea.picture_url...)` we are using the Ruby `image_tag` *helper* which translates to an HTML `<img>` tag (used to define images in HTML) but by default retrieves images from the folder public/images, which is where our uploaded images are stored. The `image_tag` helper also allows us to insert a block of code which creates a path to an image associated with a particular idea (`@idea.picture_url`).

You will notice that within this block of code you are implementing we are also able to set a default width for each image (`:width => 600`). The final line of code `if @idea.picture?` tells Rails to check the corresponding database table to see whether a picture exists before rendering the code underneath.


================================================
FILE: _pages/guide.md
================================================
---
layout: guide
title: Host your own Rails Girls event
descriptive: "Want to organize your own Rails Girls workshop? Follow this guide to learn how."
permalink: guide
---

# The How to Guide

## Hosting your first Rails Girls event

Our aim is to give tools for women to understand technology. The Rails Girls events do this by providing a great first experience on building the Internet.

Rails Girls was founded in end of 2010 in Helsinki. Originally intended as a onetime event, we never thought we'd see so many local chapters all around the world! This guide has been put together to help you get started.

If you want to organize an event, start by filling out <https://railsgirls.com/inyourcity> and you'll receive more instructions.

A list of upcoming events can be viewed at [railsgirls.com](https://railsgirls.com).

You are also welcome to join our [organizers' Slack discussion forum](https://rails-girls-slack.herokuapp.com/).

### The Basics
Rails Girls events are non-profit. We don’t charge the participants and do not pay for coaches or speakers. Participants don’t need any previous knowledge about programming and there are no age-limitations. All the participants need is a laptop and some curiosity.

The two-day event includes a lot of small group working and short focused talks on programming, design and web. No panel discussions or podium-talks - the spirit should be informal and hands-on. The more you can remove abstractions and add inclusivity the better.

#### Rails Girls philosophy

* Show spark, personality and keep in mind the big picture. Explain, repeat and always tie what you're telling into a larger context.
* Internet was made by people and it doesn’t break by a little tinkering. Continuously show the human side: encourage coaches to talk about open source communities, their programming idols and their aspirations.
* Copy-pasting rules. Programming per se isn’t central - you can't really learn to speak Chinese in one day, in a similar manner you can only learn the basic vocabulary and expressions in coding. The goal of every event is to make something visible!
* Girls run this world! But also women, ladies, even boys are allowed in. More than semantics we're interested in a mindset. Both founders were born in the Spice Girls era, they don't see the word girl as condescending or cutesy-cute.

#### Codes of Conduct

Rails Girls events are inclusive, friendly and safe environments. They have zero tolerance of harassment or bullying. You can include a Code of Conduct to your event. Below are examples:

* [Rails Girls Summer of Code Code of Conduct](https://railsgirlssummerofcode.org/about/code-of-conduct/)
* [PyLadies Code of Conduct](https://www.pyladies.com/CodeOfConduct/)
* [Geek Feminism Wiki Anti Harassment example](https://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy)
* [Conf Code of Conduct](https://confcodeofconduct.com/)
* [Rails Girls DC Code of Conduct](https://docs.google.com/document/d/1XEnFI3R30IiGXOpC4idb0ku3pw8OoJcBpG9mg3iKiAo/edit)
* [Rails Girls NZ Code of Conduct](https://docs.google.com/document/d/1EiTZ-__VDuXpN1OqgVKnYr2Km_N3fD9WWN3g5cv5hAA/edit)

### Example Program

Every Rails Girls event starts with an installation-fest where the setup is pre-installed to the girl's computers. See [the install guide](/install) for readymade instructions. The installation-fest can include short talks, but the main point is to offer some sparkling wine, get everything set for the next day and the women to know each other. The timeframe is tentative - you know your audience and what suits them best. We've hosted events both during weekend and weekdays. Also, doing two evenings (4PM - 22 PM) might be a more suitable solution for your community needs.

#### Learning objectives of the workshop:

* Understanding the difference between a dynamic and static web page.
* Vocabulary of the web: developing a basic understanding of what components make a web application. Understanding the ABCs of coding: strings, methods, variables, arrays, exclamations, chaining, hashed, symbols, blocks.. as well as the tools (terminal, browser, text editor). Creating a conceptual understanding of the web's building blocks: programming languages, frameworks, databases, infrastructure.
* Have an idea of how to move forward in the programming world: both online and offline.

#### Friday evening: Installation

19:00 - 21:00 Installations and getting to know each other
*Hint*: Have a coach table where problematic computers can be brought.

Some installations will fail: be prepared to set women up in pairs, don't use endless amounts of time.

Decorate the place with balloons and posters. Put a fun <a href="https://open.spotify.com/playlist/1fgkUFCFDrSn621kf4iHhr">playlist</a> together for the evening.

Come up with activities to break the ice: ask the girls to write why they are attending the event on post-its or to draw and describe their dream web app.

Remember to do a #FridayHug!

21:00 -> Coach dinner (optional)
Go through the application with the coaches during dinner.


#### Saturday: Workshop

09:00 - 10:00 Registration and coffee
*Hint* Reserve enough time for people to mingle and to solve any problems there might be with installations. Give out workbooks, collect acronyms for the Bento exercise.

10:00 - 10:10 Welcoming words
*Hint* Mention sponsors, show what we'll build, tell what programming is.

10:30 - 11:00 UX workshop

11:00 - 11:30 Introduction to programming
*Hint* Ask one of the coaches to do this. Explain why learning Ruby basics is important even though they'll be using Rails.

Themes to cover:

+ The difference between dynamic and static websites: what are web apps?
+ What are programming languages? What is Rails?
+ The tools we’ll be using: browser, terminal, code editor, folder structure

Show & tell with <a href="https://ruby.github.io/TryRuby/">TryRuby</a>, first three-four exercises all together.

11:30 - 13:00 Workshop time
Going (slowly!) through the curriculum at <a href="/app">guides.railsgirls.com/app</a>. Stop to explain what you’re doing and what the different concepts mean.

Try to aim for simple explanations even with the cost of accuracy. You don’t need to talk about all underlying concepts. Just try to answer questions when they arise, or move on if they’re too hard or out of scope. You are not here to teach perfect coding skills but to show how to get stuff done. One has to learn how to build web apps before learning how to do it well.

Concepts to cover:
+ Rails Generators
+ Scaffolds: Rails App Structure
+ Gem Management
+ MVC, REST/Resources
+ Models and Active Record
+ Controllers and ActionController
+ Views and ERB

*Tips:* Coaches are people too. They are doing this for the first time too. Teaching might be hard and intimidating, so remember to be available to help coaches or groups with difficult situations or just provide support and encouragement.

13:00 - 14:00 Lunch

14:00 - 14:30 Bentobox exercise
Putting technical jargon into a context with a conceptual model called Bentobox.

Two exercises: 1) Going through the 10 technical concepts with the physical Bentobox boards.  2) Going through the words the women have themselves submitted with the coaches.

+ [Bentobox slidedeck](https://speakerdeck.com/railsgirls/rails-girls-bentobox-exercise)
+ [Instruction video](https://vimeo.com/39049632)

14:30 - 18:00 Workshop time.

Time to continue working on the applications. Monitor the situation: when it seems like people have a hard time concentrating, have the coaches or other speakers give quick lightning talks.

Example topics for lighting talks:

+ Real (female) programmers telling what their career has been like.
+ Design: UX & UI. Making mockups together either with paper or computer.
+ Fun ways of explaining technical concepts and recent frameworks: what is CoffeeScript explained in 80s pop songs? How would you describe GitHub? What coding and creative writing have in common?
+ Show us something real: don’t speak in abstractions, be specific and tell stories.

Once everyone has finished their app, there is time to extend the application by modifying the CSS, implementing commenting systems etc. Allow enough time for experimentation.

19:00 After party  
*Hint:*
Invite everyone, also the local developers, boys, those who weren't accepted, to join!

[Fork this project on GitHub][github], add yourself, and send us a pull request.

[github]: https://github.com/railsgirls/railsgirls.github.com "Fork on GitHub"

#### Materials

+ [Download materials](https://speakerdeck.com/railsgirls)

### Promotion of Rails Girls

Every Rails Girls workshop will get a custom website at railsgirls.com/city where the information is collected and then stored. For past cities, see <https://railsgirls.com/events.html>

You can also set up your own Facebook and X page (remember to add links to your workshop's page!) or whatever service is popular in your community. Promoting the event through social media can go a long way these days, but make sure you have somebody to take care of the chosen channels. Some tips:

* Keep the tone of posts friendly, positive and welcoming. Be direct in inviting fans/followers to share the event with their friends.
* Photos are especially powerful messengers. Create your own graphics (*some ideas: "I'm a Rails Girl" Facebook cover for the event, word cloud with first names of women who signed up, an infographic of applications*) or promote photos from other workshops if this is your event. Follow other Rails Girls pages and account to get ideas for content and pass it along to your community.
* Try various pitches for events to attract different types of women; some will be in it for the fun and meeting new people, some to learn new things, some will be fueled by the desire to show guys that women can do anything. No need to focus on just one group!
* Don't be afraid to publicly thank women, coaches, blogs, media and other supporters who help you spread the word about your workshop for their support.
* If your language supports it, use feminine forms when addressing women.

While the event is underway, remember to take pictures, collect tweets and ask questions of the participants. You'll be thankful for all of that for your next event. We love to write blog posts about the speaker and participant experiences. A list of the coaches is also required.

+ [Download materials](https://speakerdeck.com/railsgirls)

#### Website
E-mail contact(a)railsgirls.com and ask to be included in the repo. Look for readme.txt for further instructions! Before making a site you should have at least two coaches and one sponsor onboard.


+ [Counter for the site](https://github.com/ys/rails-girls-count#readme)

#### How to find local developers?

* Google. Almost every country has some sort of a Rails or Ruby community (sometimes called Ruby Brigade or Ruby Tuesday). Look for [Hackernews](https://news.ycombinator.com) meetups, [GitHub](https://www.github.com) contributors or [Dribbble](https://dribbble) draftees. Find the local open source scene. Surf the technology conferences of [Ruby-themed ones](https://rubyconferences.org/), but others are cool too) and meetups at [meetup.com](https://www.meetup.com). Call software development houses, big and small. Don't forget IRC and podcasts!

* Check out hashtags like #rails #ruby and #opensource from [Twitter search](https://twitter.com/#!/search-home). To find people from, say, close to NYC, use the following search operators "near:NYC within:15mi". Some countries have specific hashtags like #Rubysur and #RubyArg they use, remember to ask!

* Startup community. Startup Digest is a good beginning point for events and communities.

* Often there are one or two key people who will be able to introduce you further. The technology world is surprisingly connected.

#### How to find participants?

* Use social media: Facebook, X & local networks such as Weibo. Friends, girlfriends, co-workers!

* Local [Girls in Tech](https://twitter.com/#!/gitweet), [DevChix](http://www.devchix.com/), [Geek Girl](https://www.geekgirlmeetup.com/) chapters etc. Check out also [Meetup.com](https://www.meetup.com/). X lists like @anitaborg's [Tech Women Programs](https://twitter.com/#!/anitaborg_org/tech-women-programs) and similar.

* Think outside the box: universities, book clubs, music stores, design agencies, [Etsy](https://www.etsy.com). We want women who are interested in technology, but they can still have very varied backgrounds.

#### How to get press?

One of the big aims of Rails Girls is to make it more mainstream for women to build the web. That’s why we like to engage the local press and highlight the participants and their enthusiasm. We’d be happy to help prepare a press-release for the media. Check out [railsgirls.com/press](https://railsgirls.com/press) for more. If you're working with a big company as a sponsor, their PR department might be able to help you spread the message about the workshop.

Send the press release to local blogs, find contact at various media outlets. The more doors you knock on, the greater you chance of getting through. Make a list of journalists and bloggers you contact, mark those that respond to your emails, so they can be the first ones to receive your next press release. You can also write a press release after the event that includes photos and statements from satisfied participants.

### Sponsorships

Rails Girls talks to a demographic that might be hard to reach other ways: women who have an interest in technology, who are possible users, employees or partners of the sponsoring company.

We are looking for sponsors who are active participants in the local technology scene, whether it’s a startup or a big corporation, a non-profit or a government organization.

Also non-traditional technology companies can be approached: kids stores, universities, women's magazines, beverage brands etc. They all should however have some affiliation or interest in technology.

Rails Girls should always be kept non-profit: if there's money left, it should be used to support the future activities of the attendees. Don’t forget that you don’t need that much funding and even a two-person startup could be very willing to chip in.

We advice against having only one sponsor (cannabilize the event) or having a SPONSOR NAME edition of the Rails Girls workshop. The Rails Girls brand is not meant for the commercial advancement of a single company.

### Example letter for sponsors

Dear xxx,

We are organizing a Rails Girls programming workshop in (insert city) on (insert dates).

Rails Girls is a two-day non-profit event for women of all ages to give them a great first experience in software craftsmanship. We aim to give the tools to understand technology along with the community and inspiration to get started.

Rails Girls is not just about programming, it’s about building things. During the workshop, we’ll build an application and also have inspiring lightning talks and exercises.

For a closer look, please see www.railsgirls.com for past events and coverage. Here’s also a short video on the Berlin event held in April 2012: <https://vimeo.com/40852182>

We are now looking for sponsors to help us realize this all.
We’d love to have your support!

Yours, name



### How much does it cost?

The costs below are estimated for 30 participants, 10 coaches - but they may vary a lot. It's easiest to try to get a local sponsor to pay the bills directly or partner with someone who has a set account to handle money. These calculations are done in Finland, in €, where food & alcohol is very expensive, but spaces are often free. All in all you should be able to organise an event easily for a little over a thousand euros.

+ **Sparkling wine + cups** for the installation festival. 6 bottles, 6 euros a bottle. 36 euros.

+ **Breakfast Coffee**, pastry. 40 times around 5 euros. 200 euros

+ **Lunch.** Catered lunch can be around 15 euros, but you can do with a lot less by cooking yourself.  Add some water and coffee (50 euros). 650 euros.

+ **Marketing materials.** Printing workbooks, ordering stickers, posters and other swag. Again, varies a lot, maybe you can use someones printer, but at least around 200 should be reserved.

+ **Coach dinner.** At a restaurant or homemade. A way to say thank you to the coaches for their volunteer work. Around 20 euros per head. 200 euros.

+ **Space.** Try to get this one sponsored/free, they can be really expensive. Often startups are co-operative and can offer their space for use (esp. on weekends).	0 - XXXX euros.

+ **Afterparty.** It's nice if you can throw a good party with free beverages, but can also be done low-key in a local bar or on set in the park!	0 - XXXX euros.

+ **Travel expenses.**	If you don't have any RG-team members in your country, consider inviting us over. We don't need fancy hotels, promise! Same if you want to invite speakers to your event. 	0 - XXX

+ *Total 1286 euros*.

__What do sponsors get?__

* Logo on event website
* Table space at event, opportunity to distribute handouts and/or swag
* A chance to speak to attendees for 5 minutes
* In most events there are official pictures taken that the sponsors can use afterwards

Don’t give out the participant info, but sponsors are free to hang out at the event and be sure to include a short message to the sponsor in a thank-you note. Sponsor swag may be included in the goodie bag to an extent, but it should be something tasteful, not trashy and/or related to women.



---

## FAQ

#### Who can organise a Rails Girls workshop?

Anyone. What we look for is a group of people dedicated in making this a stellar first experience in the world of web making for women. What we hope to see is some (not all) of the following:

* Contacts to the local developer scene. We are pretty technology agnostic, so it doesn’t have to be purely Ruby & Rails people. In practice every event needs 5 or more coaches (the number of coaches depends on the number of women you're planning to accept) that have basic knowledge of Rails and two days to contribute. In general the events have been around 25 - 40 people strong.
* Event organisation know-how. Not heaps, but some practicalities under the belt.
* An inkling of an idea where to look for women interested in technology. University, literature, arts, sports - we try to look for people who are interested in Internet, but do not have experience in coding.
* Willingness to guide the women in the future if they have questions or want to organize their own events or find local developer gatherings.

Start by filling out <https://railsgirls.com/inyourcity> and someone from our team will be in contact

#### Where can I find all the materials for posters, nametags, sample presentations and such?
Check out below, and let us know if something is missing!

+ [Download materials](https://speakerdeck.com/railsgirls)

#### What kind of venue is needed?

We recommend choosing a venue with a built-in infrastructure for around 30-50 persons. For a programming event, this means:

* High-speed, tested Internet. There’s going to be over 30 computers online all the time. Add to that mobilephones, streaming music, funny videos and you get the picture!
* Space for 4-6 person groups to gather together: chairs and tables, sometimes big pillows will do! This doesn’t have to be in the same room.
* Possibility to set up extension chords and a projector.
* Enough electric outlets to spare. Some women might have older laptops that will need to be plugged in at all times.
* Location for food and beverage setup - lunch space for catering or a nearby lunch venue.
* External monitors for teams are encouraged but not mandatory, helps the coaches show what is happening in the code.
* Whiteboards can be helpful for coaches to explain more abstract concepts. Alternatively, paper and pen work just fine. Just have something at hand people can draw on.

Ask where local developer meetings are usually hosted. Often co-working spaces are also willing to negotiate deals to gain some visibility among new people.

#### What is expected from the coaches?

Rails Girls events are organized around small groups, maximum of 4-5 persons per one coach. If possible, try to have groups of 3 women for each coach. For instance, if you're doing an event for 30 women, aim for having 10 coaches (a few more for backup don't hurt). We know this isn't always possible, but do try not to have groups of more than 5 women, so the coach can still answer all questions in the group.

The coaches don’t need to be hardcore experts on Rails - basic knowledge and willingness to explain trumps expertise. So, if your local Rails community isn't very strong, do expand your search. You can have a mix of Rails experts and people with web development expertise in other frameworks. We are looking for people who like answering questions and can keep an upbeat and positive atmosphere through a period of 8 hours!

You can get to know the curriculum by checking out [the guides index](/). There is also always a pre-event coach dinner where we’ll go through some pedagogical suggestions and check everyone knows what is happening. Avoid jargon, tie examples to what your doing, encourage asking questions. The installation instructions can be found in [the install guide](/install). We also understand that coaches are human and that for most of the people this is the first time teaching something. Worry not - the women have always been really happy with whatever they learn and just the chance to ask questions is enough.


We hope the coaches are ok with having their name and twitter-id/github/some mean of contact on railsgirls.com so the women always have a local face to answer their questions.

In addition, we encourage coaches to come up with additional exercises for the group. After completing the ideation app many women will want to try tweaking the look & feel of the site, implementing commenting, Facebook sharing, pushing the app to Heroku, etc.

#### How to find coaches?

Ask around, ask sponsors (tech companies), ask anyone to help you out. Once you do get some coaches on board, they can help you out with their own contacts. Influential bloggers or X users in your local dev community can help you out by broadcasting a call for coaches. *Hint: You can also thank coaches for their help by providing a spot at the workshop for their girlfriends ;)*

##### Sample letter for potential coaches

"Dear community member,

We wish to invite you to take part in the Rails Girls event on (insert date). The event is aimed for women of all ages with no previous programming experience, but a lot of passion to building things. Rails Girls is an international non-profit, volunteer-based workshop. We've had events in Shanghai, Berlin, Helsinki, and Singapore. We expect to receive around a 100 applications.

In addition to giving a safe and fun first experience to coding for the women we want to engage them with local developers, open source, and the startup scene. We've attached some information on what coaching requires in practice. In addition, we have room for small lightning talks on technical subjects. If you have something you'd like to speak about, let us know.

For more information about the non-profit event, check railsgirls.com or guides.railsgirls.com

(You can also include the chapter "What is expected from the coaches" to the mail)"

---



#### What materials do I get?

Each Rails Girls event gets a specific webpage.

In addition we’ll help you out with the goodie bags, poster templates, workbooks and other swag like stickers, reflectors and so forward. All of the materials can be found on this site. You can also ask the sponsors to include some sponsor materials if they wish. We are always looking for creative outlets for the Rails Girls brand, if you have ideas, let us know!

So far we've had

* Stickers
* Reflectors
* Tattoos

Also, check out:

+ [Download materials](https://speakerdeck.com/railsgirls)

#### How do I choose attendees?

In the form we ask only two questions: do you have any previous background in coding and why would you be a good participant for Rails Girls

Rails Girls is intended for anyone and we want to keep it flexible enough for learners any age. However, make clear to the attendees what to expect: Rails Girls won’t make anyone into a coder, so people looking for i.e career change will be disappointed. On the other hand we like people with very diverse backgrounds and loads of enthusiasm.

After selecting participants we generally split them into three groups:

1. people with no previous programming experience
2. people with some front-end experience (HTML, CSS, Javascript) and
3. people with a little experience in programming or a background in computer sciences. You can use the different name-tags for each group if you want to (rubies, foxes, octocats, rails..)


##### Sample letter of acceptance

Title: Rails Girls workshop - welcome!

Dear attendee,

Congratulations! We’re happy to invite you to join in on the  Rails Girls workshop in (insert city). We hope that this workshop will provide you a great first experience on building web apps.

What happens next?

(Insert date for installation fest) starts at (insert time) with an installation fest - so please bring your laptop with you! You should also try to pre-install Rails with instructions from </install>

We wil
Download .txt
gitextract_3vukf4_h/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── deploy.yml
├── .gitignore
├── .ruby-version
├── 404.html
├── Gemfile
├── LICENSE
├── README.md
├── _config.yml
├── _includes/
│   ├── analytics.html
│   ├── footer.html
│   ├── github-corner.html
│   ├── header.html
│   ├── main-guide-intro.html
│   └── main_guides.md
├── _layouts/
│   ├── default.html
│   ├── guide.md
│   └── main_guide.md
├── _pages/
│   ├── activeadmin.md
│   ├── app.md
│   ├── coach.md
│   ├── commenting.md
│   ├── continuous-codeship.md
│   ├── continuous-snap-ci.md
│   ├── continuous-travis.md
│   ├── contributing.md
│   ├── deployment/
│   │   ├── anynines.md
│   │   ├── digital-ocean.md
│   │   ├── engineyard.md
│   │   ├── fly-io.md
│   │   ├── heroku.md
│   │   └── openshift.md
│   ├── deployment.md
│   ├── design-using-html-and-css-chinese.md
│   ├── design.md
│   ├── devise.md
│   ├── diary-app.md
│   ├── github.md
│   ├── gravatar.md
│   ├── guide-to-the-guide.md
│   ├── guide.md
│   ├── how-to-continue-with-programming.md
│   ├── html-and-css.md
│   ├── install/
│   │   ├── linux.md
│   │   ├── macos.md
│   │   ├── replit.md
│   │   ├── virtual-machine.md
│   │   └── windows.md
│   ├── install.md
│   ├── new-homepage.md
│   ├── new-page.md
│   ├── passenger.md
│   ├── remote-pairing-for-the-win.md
│   ├── ruby-atm.md
│   ├── ruby-game.md
│   ├── ruby-intro.md
│   ├── shoulda-matchers.md
│   ├── simple-app.md
│   ├── sinatra-app-tutorial.md
│   ├── sinatra-html.md
│   ├── sinatra.md
│   ├── start.md
│   ├── test-driven-development.md
│   ├── testing-rspec.md
│   ├── thumbnails.md
│   ├── tools.md
│   ├── touristic-autism_basic-app.md
│   ├── touristic-autism_continuous-deployment.md
│   ├── touristic-autism_design.md
│   ├── touristic-autism_git.md
│   ├── touristic-autism_google-map.md
│   ├── touristic-autism_image-upload.md
│   ├── touristic-autism_intro.md
│   ├── touristic-autism_resource-modeling.md
│   ├── touristic-autism_resource-rating.md
│   ├── touristic-autism_static-pages-tdd.md
│   ├── twitter-widget.md
│   ├── uploads.md
│   └── videos.md
├── _plugins/
│   └── coach.rb
├── css/
│   ├── code.css
│   └── style.css
├── index.html
└── js/
    ├── guides.js
    ├── js.cookie.js
    └── mobile-menu.js
Download .txt
SYMBOL INDEX (12 symbols across 4 files)

FILE: _plugins/coach.rb
  type Jekyll (line 1) | module Jekyll
    class CoachTag (line 4) | class CoachTag < Liquid::Block
      method render (line 5) | def render(context)

FILE: js/guides.js
  function saveOs (line 1) | function saveOs(os) {
  function loadOs (line 5) | function loadOs() {
  function detectOs (line 16) | function detectOs() {
  function addIcons (line 31) | function addIcons() {
  function initializeOsSwitchers (line 37) | function initializeOsSwitchers() {
  function topFunction (line 100) | function topFunction() {

FILE: js/js.cookie.js
  function assign (line 15) | function assign (target) {
  function init (line 45) | function init (converter, defaultAttributes) {

FILE: js/mobile-menu.js
  function toggleMobileMenu (line 1) | function toggleMobileMenu() {
Condensed preview — 86 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (484K chars).
[
  {
    "path": ".github/dependabot.yml",
    "chars": 118,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: 'github-actions'\n    directory: '/'\n    schedule:\n      interval: 'weekly'\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 1595,
    "preview": "name: Deploy site\n\non:\n  # Runs on pushes targeting the default branch\n  push:\n    branches: [\"main\"]\n\n  # Allows you to"
  },
  {
    "path": ".gitignore",
    "chars": 32,
    "preview": ".bundle/\n_site/\n.DS_Store\n*.swp\n"
  },
  {
    "path": ".ruby-version",
    "chars": 6,
    "preview": "3.2.8\n"
  },
  {
    "path": "404.html",
    "chars": 331,
    "preview": "---\nlayout: default\ntitle: \"Page not found\"\npermalink: /404.html\n---\n\n<div class=\"box text-center\">\n  <h1>Page not found"
  },
  {
    "path": "Gemfile",
    "chars": 85,
    "preview": "source \"https://rubygems.org\"\n\ngem \"jekyll\"\ngem \"jekyll-redirect-from\"\ngem \"webrick\"\n"
  },
  {
    "path": "LICENSE",
    "chars": 101,
    "preview": "Creative Commons Attribution-Share Alike 3.0 License.\nhttps://creativecommons.org/licenses/by-sa/3.0\n"
  },
  {
    "path": "README.md",
    "chars": 3359,
    "preview": "# Rails Girls Guides\n\n<a href=\"https://railsgirls.com\" target=\"_blank\"><img alt=\"Rails Girls\" src=\"/images/rails-girls-l"
  },
  {
    "path": "_config.yml",
    "chars": 550,
    "preview": "permalink: pretty\nmarkdown: kramdown\ninclude:\n  - _pages\nexclude:\n  - \".rvmrc\"\n  - \".rbenv-version\"\n  - \".ruby-version\"\n"
  },
  {
    "path": "_includes/analytics.html",
    "chars": 520,
    "preview": "<script type=\"text/javascript\">\n  //<![CDATA[\n  var _gaq = _gaq || [];\n  _gaq.push(['_setAccount', 'UA-19631067-3']);\n  "
  },
  {
    "path": "_includes/footer.html",
    "chars": 455,
    "preview": "<footer>\n  <p>\n    This work is licensed under a\n    <a href=\"https://creativecommons.org/licenses/by-sa/3.0/\">Creative "
  },
  {
    "path": "_includes/github-corner.html",
    "chars": 1423,
    "preview": "<a\n    href=\"{{ site.source_url }}{{ page.path }}\"\n    class=\"github-corner\"\n    aria-label=\"Contribute to the guide on "
  },
  {
    "path": "_includes/header.html",
    "chars": 1455,
    "preview": "<header>\n  {% include github-corner.html %}\n  <div class=\"container\">\n    <div class=\"visible-desktop\">\n      <a class=\""
  },
  {
    "path": "_includes/main-guide-intro.html",
    "chars": 190,
    "preview": "<div class=\"guide-notice\">\n  This guide is a part of the <a href=\"/#guides\">Rails Girls workshop main guides</a>. Make s"
  },
  {
    "path": "_includes/main_guides.md",
    "chars": 3211,
    "preview": "<hr>\n\nIf you're ever stuck during a guide, please ask your coach for help and also consult this [handy cheatsheet for Ru"
  },
  {
    "path": "_layouts/default.html",
    "chars": 2939,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    {% capture page_title_capture %}\n      {% if "
  },
  {
    "path": "_layouts/guide.md",
    "chars": 133,
    "preview": "---\nlayout: default\n---\n\n<article class=\"guide\">\n{{ content }}\n<hr>\nWant to learn more? <a href=\"/\">View more guides!</a"
  },
  {
    "path": "_layouts/main_guide.md",
    "chars": 168,
    "preview": "---\nlayout: default\n---\n\n<article class=\"guide\">\n{{ content }}\n{% capture guides %}\n{% include main_guides.md %}\n{% endc"
  },
  {
    "path": "_pages/activeadmin.md",
    "chars": 3832,
    "preview": "---\nlayout: guide\ntitle: Adding a back-end with Active Admin\npermalink: backend-with-active-admin\n---\n\n# Adding a back-e"
  },
  {
    "path": "_pages/app.md",
    "chars": 8408,
    "preview": "---\nlayout: main_guide\ntitle: Build your first app\ndescription: \"Start building your first Ruby on Rails app with Rails "
  },
  {
    "path": "_pages/coach.md",
    "chars": 8639,
    "preview": "---\nlayout: guide\ntitle: Guides\ndescriptive: \"The guide for coaches to prepare their participation in a Rails Girls work"
  },
  {
    "path": "_pages/commenting.md",
    "chars": 7992,
    "preview": "---\nlayout: main_guide\ntitle: Add commenting functionality to your app\ndescription: \"Allow other people to leave comment"
  },
  {
    "path": "_pages/continuous-codeship.md",
    "chars": 5216,
    "preview": "---\nlayout: guide\ntitle: Continuous Deployment - cuz less hassle\npermalink: continuous\n---\n\n# Continuous Deployment with"
  },
  {
    "path": "_pages/continuous-snap-ci.md",
    "chars": 4584,
    "preview": "---\nlayout: guide\ntitle: Continuous Deployment - cuz less hassle\npermalink: continuous-snap-ci\n---\n\n# Continuous Deploym"
  },
  {
    "path": "_pages/continuous-travis.md",
    "chars": 6722,
    "preview": "---\nlayout: guide\ntitle: Continuous Deployment - cuz less hassle\npermalink: continuous-travis\n---\n\n# Continuous Deployme"
  },
  {
    "path": "_pages/contributing.md",
    "chars": 1559,
    "preview": "---\nlayout: guide\ntitle: Contributing a Guide\ndescription: \"Contribute back to the Rails Girls community with your own g"
  },
  {
    "path": "_pages/deployment/anynines.md",
    "chars": 2997,
    "preview": "---\nlayout: main_guide\ntitle: Rails Girls on anynines\ndescription: \"Deploy your app to Anynines by following this guide."
  },
  {
    "path": "_pages/deployment/digital-ocean.md",
    "chars": 4651,
    "preview": "---\nlayout: main_guide\ntitle: Rails Girls on DigitalOcean\ndescription: \"Deploy your app to DigitalOcean by following thi"
  },
  {
    "path": "_pages/deployment/engineyard.md",
    "chars": 5131,
    "preview": "---\nlayout: main_guide\ntitle: Rails Girls on Engine Yard\ndescription: \"Deploy your app to Engine Yard by following this "
  },
  {
    "path": "_pages/deployment/fly-io.md",
    "chars": 4995,
    "preview": "---\nlayout: main_guide\ntitle: Put your app online with Fly.io\ndescription: \"Deploy your app to Fly.io by following this "
  },
  {
    "path": "_pages/deployment/heroku.md",
    "chars": 6379,
    "preview": "---\nlayout: main_guide\ntitle: Put your app online with Heroku\ndescription: \"Deploy your app to Heroku by following this "
  },
  {
    "path": "_pages/deployment/openshift.md",
    "chars": 10985,
    "preview": "---\nlayout: main_guide\ntitle: Rails Girls on OpenShift\ndescription: \"Deploy your app to OpenShift by following this guid"
  },
  {
    "path": "_pages/deployment.md",
    "chars": 858,
    "preview": "---\nlayout: main_guide\ntitle: Put your app online\ndescription: \"Publish your app online on one of the many available web"
  },
  {
    "path": "_pages/design-using-html-and-css-chinese.md",
    "chars": 1767,
    "preview": "---\nlayout: guide\ntitle: 使用HTML和CSS美化你的应用\npermalink: design-html-css-chinese\n---\n\n1.美化header样式\n\n+ 打开文件 `app/assets/style"
  },
  {
    "path": "_pages/design.md",
    "chars": 4353,
    "preview": "---\nlayout: main_guide\ntitle: Style the idea pages using HTML and CSS\ndescription: \"Make your app look even better using"
  },
  {
    "path": "_pages/devise.md",
    "chars": 4039,
    "preview": "---\nlayout: guide\ntitle: Adding Authentication with Devise\ndescription: \"Let users of your Rails app sign in using Devis"
  },
  {
    "path": "_pages/diary-app.md",
    "chars": 23730,
    "preview": "---\nlayout: guide\ntitle: Rails Girls Diary tutorial\npermalink: diary-app\n---\n\n# Create your first diary app with Ruby on"
  },
  {
    "path": "_pages/github.md",
    "chars": 10967,
    "preview": "---\nlayout: main_guide\ntitle: Push your app to GitHub\ndescription: \"Share your code with others by pushing your app's co"
  },
  {
    "path": "_pages/gravatar.md",
    "chars": 2144,
    "preview": "---\nlayout: guide\ntitle: Adding Gravatar to you app\ndescription: \"Load user avatars using the Gravatar service. That way"
  },
  {
    "path": "_pages/guide-to-the-guide.md",
    "chars": 22635,
    "preview": "---\nlayout: guide\ntitle: The Guide to the Guide\ndescriptive: \"The guide for coaches to follow along with the guides the "
  },
  {
    "path": "_pages/guide.md",
    "chars": 32209,
    "preview": "---\nlayout: guide\ntitle: Host your own Rails Girls event\ndescriptive: \"Want to organize your own Rails Girls workshop? F"
  },
  {
    "path": "_pages/how-to-continue-with-programming.md",
    "chars": 6197,
    "preview": "---\nlayout: guide\ntitle: \"After The Event: How To Continue With Programming\"\ndescription: \"A guide to keep you going wit"
  },
  {
    "path": "_pages/html-and-css.md",
    "chars": 6834,
    "preview": "---\nlayout: main_guide\ntitle: Style your app using HTML and CSS\ndescription: \"Give your app a new look with HTML and CSS"
  },
  {
    "path": "_pages/install/linux.md",
    "chars": 2515,
    "preview": "---\nlayout: main_guide\ntitle: Setup on Linux\ndescription: \"Install Ruby and Rails on your Linux computer and get prepare"
  },
  {
    "path": "_pages/install/macos.md",
    "chars": 7187,
    "preview": "---\nlayout: main_guide\ntitle: Setup on Mac\ndescription: \"Install Ruby and Rails on your Mac computer and get prepared fo"
  },
  {
    "path": "_pages/install/replit.md",
    "chars": 2570,
    "preview": "---\nlayout: main_guide\ntitle: Setup on Replit\ndescription: \"Prepare development of your app on the Replit service to dev"
  },
  {
    "path": "_pages/install/virtual-machine.md",
    "chars": 4992,
    "preview": "---\nlayout: main_guide\ntitle: Setup on a Virtual Machine\ndescription: \"Prepare development of your app using a Virtual M"
  },
  {
    "path": "_pages/install/windows.md",
    "chars": 8033,
    "preview": "---\nlayout: main_guide\ntitle: Setup on Windows\ndescription: \"Install Ruby and Rails on your Windows computer and get pre"
  },
  {
    "path": "_pages/install.md",
    "chars": 3026,
    "preview": "---\nlayout: main_guide\ntitle: Setup recipe for Rails Girls\ndescription: \"Install Ruby and Rails on your computer and get"
  },
  {
    "path": "_pages/new-homepage.md",
    "chars": 2685,
    "preview": "---\nlayout: main_guide\ntitle: Add a new homepage\ndescription: \"Customize your app's homepage with your own page.\"\npermal"
  },
  {
    "path": "_pages/new-page.md",
    "chars": 4427,
    "preview": "---\nlayout: main_guide\ntitle: Add a new page to your app\ndescription: \"Add more pages to your Rails app by generating co"
  },
  {
    "path": "_pages/passenger.md",
    "chars": 5553,
    "preview": "---\nlayout: guide\ntitle: Rails Girls on Passenger\npermalink: passenger\n---\n\n# Ease up development with Phusion Passenger"
  },
  {
    "path": "_pages/remote-pairing-for-the-win.md",
    "chars": 3649,
    "preview": "---\nlayout: guide\ntitle: Remote Pairing For the Win!\ndescription: \"Continue working together and learning remotely after"
  },
  {
    "path": "_pages/ruby-atm.md",
    "chars": 11010,
    "preview": "---\nlayout: guide\ntitle: Ruby ATM\npermalink: ruby-atm\n---\n\n# Ruby ATM\n\n*Created by Joshua Paling, [@joshuapaling](https:"
  },
  {
    "path": "_pages/ruby-game.md",
    "chars": 3855,
    "preview": "---\nlayout: guide\ntitle: Write a little game in Ruby!\npermalink: ruby-game\n---\n\n# Write a little game in Ruby!\n\n*Created"
  },
  {
    "path": "_pages/ruby-intro.md",
    "chars": 18168,
    "preview": "---\nlayout: guide\ntitle: Introduction to Ruby\ndescription: \"Learn how the Ruby language syntax works and how to make dyn"
  },
  {
    "path": "_pages/shoulda-matchers.md",
    "chars": 3716,
    "preview": "---\nlayout: guide\ntitle: Simplify your tests with shoulda matchers\npermalink: testing-shoulda-matchers\n---\n\n# Simplifyin"
  },
  {
    "path": "_pages/simple-app.md",
    "chars": 13782,
    "preview": "---\nlayout: guide\ntitle: Simpler Rails Girls App Tutorial\npermalink: simpleapp\n---\n\n# Rails Girls App Tutorial\n\n*Created"
  },
  {
    "path": "_pages/sinatra-app-tutorial.md",
    "chars": 8831,
    "preview": "---\nlayout: guide\ntitle: Rails Girls Sinatra tutorial\npermalink: sinatra-app\nredirect_from:\n  - sinatra-app-bg\n---\n\n# Cr"
  },
  {
    "path": "_pages/sinatra-html.md",
    "chars": 1381,
    "preview": "---\nlayout: guide\ntitle: Coffee List Display\npermalink: sinatra-html\n---\n\n# Coffee List Display\n\n*Created by Tim McEwan,"
  },
  {
    "path": "_pages/sinatra.md",
    "chars": 14552,
    "preview": "---\nlayout: guide\ntitle: Web Fundamentals Tutorial\npermalink: sinatra\n---\n\n# Web Fundamentals Tutorial\n\n*Created by Tim "
  },
  {
    "path": "_pages/start.md",
    "chars": 937,
    "preview": "---\nlayout: main_guide\ntitle: Start of the guide\ndescription: \"Start your journey to building your first Ruby on Rails a"
  },
  {
    "path": "_pages/test-driven-development.md",
    "chars": 7402,
    "preview": "---\nlayout: guide\ntitle: Test Driven Development\npermalink: test-driven-development\n---\n\n# Test Driven Development\n\n*Wri"
  },
  {
    "path": "_pages/testing-rspec.md",
    "chars": 4378,
    "preview": "---\nlayout: main_guide\ntitle: Test your app with RSpec\ndescription: \"Make sure your app doesn't accidentally break by te"
  },
  {
    "path": "_pages/thumbnails.md",
    "chars": 3982,
    "preview": "---\nlayout: main_guide\ntitle: Create picture thumbnails\ndescription: \"Optimize image uploads by creating thumbnails: sma"
  },
  {
    "path": "_pages/tools.md",
    "chars": 5127,
    "preview": "---\nlayout: main_guide\ntitle: Get to know the tools\ndescription: \"Install the required tools to make your first Ruby on "
  },
  {
    "path": "_pages/touristic-autism_basic-app.md",
    "chars": 4842,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_basic-app\n---\n\n# Basic Web Appl"
  },
  {
    "path": "_pages/touristic-autism_continuous-deployment.md",
    "chars": 7834,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_continuous-deployment\n---\n\n# Co"
  },
  {
    "path": "_pages/touristic-autism_design.md",
    "chars": 10170,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_design\n---\n\n# Design\n\n*Created "
  },
  {
    "path": "_pages/touristic-autism_git.md",
    "chars": 3383,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_git\n---\n\n# Version Control with"
  },
  {
    "path": "_pages/touristic-autism_google-map.md",
    "chars": 2782,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_google-map\n---\n\n# Show All Plac"
  },
  {
    "path": "_pages/touristic-autism_image-upload.md",
    "chars": 4523,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_image-upload\n---\n\n# Image Uploa"
  },
  {
    "path": "_pages/touristic-autism_intro.md",
    "chars": 4471,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_intro\n---\n\n# Rails Girls Touris"
  },
  {
    "path": "_pages/touristic-autism_resource-modeling.md",
    "chars": 13978,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_resource-modeling\n---\n\n# Resour"
  },
  {
    "path": "_pages/touristic-autism_resource-rating.md",
    "chars": 2967,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_resource-rating\n---\n\n# Resource"
  },
  {
    "path": "_pages/touristic-autism_static-pages-tdd.md",
    "chars": 10864,
    "preview": "---\nlayout: guide\ntitle: Touristic Autism-friendly Spots App\npermalink: touristic-autism_static-pages-tdd\n---\n\n# Test-Dr"
  },
  {
    "path": "_pages/twitter-widget.md",
    "chars": 1467,
    "preview": "---\nlayout: guide\ntitle: Twitter widget\npermalink: twitter-widget\n---\n\n# Twitter widget\n\n*Written by Asta Bevainyte, [@a"
  },
  {
    "path": "_pages/uploads.md",
    "chars": 4565,
    "preview": "---\nlayout: main_guide\ntitle: Add picture uploads\ndescription: \"Make your ideas pop with image uploads in your Rails app"
  },
  {
    "path": "_pages/videos.md",
    "chars": 5454,
    "preview": "---\nlayout: guide\ntitle: Rails Girls on video\npermalink: videos\n---\n\n# Rails Girls Happiness All Around the World\n\nThis "
  },
  {
    "path": "_plugins/coach.rb",
    "chars": 584,
    "preview": "module Jekyll\n  # A coach tag with its own styling.\n  # Content is rendered as Markdown.\n  class CoachTag < Liquid::Bloc"
  },
  {
    "path": "css/code.css",
    "chars": 3937,
    "preview": ".highlight .hll { background-color: #ffffcc }\n/*.highlight  { background: #f0f0f0; }*/\n.highlight .c { color: #60a0b0; f"
  },
  {
    "path": "css/style.css",
    "chars": 9382,
    "preview": "html {\n  --highlight: #e0330c;\n  background: #f4f4f4;\n}\n\nbody {\n  margin: 0px;\n  background: #fff;\n  color: #333;\n  text"
  },
  {
    "path": "index.html",
    "chars": 10233,
    "preview": "---\nlayout: default\ndescription: \"Learn how to make your first web app with Ruby on Rails! Sign up for a Rails Girls wor"
  },
  {
    "path": "js/guides.js",
    "chars": 3241,
    "preview": "function saveOs(os) {\n  Cookies.set(\"os\", os, { expires: 1825, path: '/' }); // expires in 5 years\n}\n\nfunction loadOs() "
  },
  {
    "path": "js/js.cookie.js",
    "chars": 4195,
    "preview": "/*! js-cookie v3.0.1 | MIT */\n/* https://github.com/js-cookie/js-cookie */\n;\n(function (global, factory) {\n  typeof expo"
  },
  {
    "path": "js/mobile-menu.js",
    "chars": 223,
    "preview": "function toggleMobileMenu() {\n  var navbarList = document.getElementById(\"navbar-list\");\n  if (navbarList.style.height ="
  }
]

About this extraction

This page contains the full source code of the railsgirls/guides.railsgirls.com GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 86 files (454.4 KB), approximately 115.8k tokens, and a symbol index with 12 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!