` | Any block of content | Yes | [Link](http://www.w3schools.com/tags/tag_div.asp) |
115 |
116 |
117 | ## CSS
118 |
119 |
120 | ### Adding a stylesheet
121 |
122 | CSS goes in a separate file, with a `.css` extension. So, for example, you might create a file called `styles.css`. Once you've created a stylesheet, you then need to include it in your HTML page, within the `` section. Make sure that the path to the file is correct!
123 |
124 | ```html
125 |
126 |
127 |
128 | ```
129 |
130 | ### Rule declarations
131 |
132 | A “rule declaration” is the name given to a selector (or a group of selectors) with an accompanying group of properties. It's how you tell the browser to style a particular element a particular way. Here's an example:
133 |
134 | ```css
135 | .my-element {
136 | font-size: 20px;
137 | color: blue;
138 | }
139 | ```
140 |
141 |
142 | ### Selectors
143 |
144 | Within a rule declaration, you can target an element (tell the browser what to apply particular styles to) in a few different ways.
145 |
146 | | Selector | Example | Description | Info/Example |
147 | | -------- | ------- | ----------- | --------- |
148 | | .class | `.intro` | Selects all elements with `class="intro"` | [Link](http://www.w3schools.com/cssref/sel_class.asp) |
149 | | #id | `#firstname` | Selects the element with `id="firstname"` | [Link](http://www.w3schools.com/cssref/sel_id.asp) |
150 | | element | `p` | Selects all `
` elements | [Link](http://www.w3schools.com/cssref/sel_element.asp) |
151 |
152 |
153 | ### Media queries
154 |
155 | To apply different styles for different screen sizes (i.e. mobile device vs. desktop computer), you can use media queries. The most common ways to use media queries is to specify a `min-width`, a `max-width`, or both together.
156 |
157 | ```css
158 | @media (min-width: 992px) {
159 | /* These styles will be applied to desktop browsers */
160 | .my-element {
161 | color: red;
162 | }
163 | }
164 |
165 | @media (min-width: 768px) and (max-width: 991px) {
166 | /* These styles will be applied to tablets */
167 | .my-element {
168 | color: green;
169 | }
170 | }
171 |
172 | @media (max-width: 767px) {
173 | /* These styles will be applied to mobile devices */
174 | .my-element {
175 | color: blue;
176 | }
177 | }
178 | ```
179 |
180 |
181 | ## Ruby
182 |
183 |
184 | ### Ruby basics
185 |
186 | For a more comprehensive guide to the very very basics of ruby, refer to [this guide](https://gist.github.com/matt297/055ee0b28c2bd79aa9783359d83f4906).
187 |
188 |
189 | ### Data types
190 |
191 | In ruby, we can store different types of data. These are the most common types (with a couple examples for each).
192 |
193 | ```ruby
194 | # A string, wrapped in quotes (single or double)
195 | first_name = 'John'
196 | last_name = "Doe"
197 |
198 | # An integer (has no decimal places)
199 | first_number = 1
200 | second_number = 10
201 |
202 | # A float (has decimal places)
203 | first_number = 5.5
204 | second_number = 8.2
205 |
206 | # A boolean (true/false value)
207 | first_value = true
208 | second_value = false
209 | ```
210 |
211 | ### Complex data stores
212 |
213 | When needed, you can also store data in more complicated ways. For instance, maybe you need to create a list of things, well, Ruby makes that easy! You can use an array to store any number of things (and each thing can be of a different type - i.e. a string, then an integer, then a float).
214 |
215 | ```ruby
216 | # Create an array (list of things of any types)
217 | grocery_list = ["Potatoes", "Bread", "Milk", "Butter"]
218 |
219 | # To get the first item from the list (returns "Potatoes")
220 | grocery_list[0]
221 |
222 | # To get the second item from the list (returns "Bread")
223 | grocery_list[1]
224 | ```
225 |
226 | For groups of related data, you can also use a hash as a different way to store the data.
227 |
228 | ```ruby
229 | # Create hash
230 | person = { name: "Matt", age: 99, favourite_book: "Harry Potter", favourite_movie: "Inception" }
231 |
232 | # Get the person's name (returns "Matt")
233 | person["name"]
234 | ```
235 |
236 |
237 | ### Logical operators
238 |
239 | When performing logic, Ruby always returns one of two things: `true` or `false`. That makes it easy for us to build programs around this behaviour. To do logic, you use operators, which are listed in the table below.
240 |
241 | | Operator | Description | Info/Example |
242 | | -------- | ----------- | ------------ |
243 | | `==` | Equal to | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
244 | | `!=` | Not equal to | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
245 | | `>` | Greater than | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
246 | | `>=` | Greater than or equal to | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
247 | | `<` | Less than | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
248 | | `<=` | Less than or equal to | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
249 | | `&&` | And (allows you to combine multiple conditions) | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
250 | | `||` | Or (allows you to combine multiple conditions | [Link](https://www.tutorialspoint.com/ruby/ruby_operators.htm) |
251 |
252 | ```ruby
253 | # Comparing two things
254 | variable_one == variable_two
255 |
256 | # Using multiple conditions
257 | variable_one == variable_two && variable_three != variable_four
258 | ```
259 |
260 |
261 | ### Logic and conditions
262 |
263 | Often times when programming, we need to perform logic, or create a set of conditions for a particular thing to happen. In Ruby, this can be done in a variety of ways. The most common is using an if/else block.
264 |
265 | ```ruby
266 | # Simple with only one condition
267 | if seconds > 60
268 | 'More than 1 minute ago.'
269 | else
270 | 'Less than 1 minute ago.'
271 | end
272 |
273 | # More complex, with a few possibilities
274 | if time_of_day == 'Morning'
275 | 'Good morning!'
276 | elsif time_of_day == 'Afternoon'
277 | 'Good afternoon!'
278 | else
279 | 'Good evening!'
280 | end
281 |
282 | # Using multiple conditions
283 | if time_of_day == 'Morning' && weather != 'Raining' do
284 | 'Happy morning! It is not raining!'
285 | end
286 | ```
287 |
288 |
289 | ### Methods
290 |
291 | In programming, you often need to re-use code multiple times. Whenver this needs to be done, you put that code inside of a method, and then you can simply run the method whenver you need that code. Methods can either accept arguments (i.e. take in values and then do something with those values), or accept no arguments (for example if you just want to print out something). To define a method, you use the `def` and `end` keywords.
292 |
293 | Remember, in Ruby, the last line of a method is automatically returned as the final value.
294 |
295 | ```ruby
296 | # Define a new method with no arguments
297 | def say_hello
298 | 'Hello world!'
299 | end
300 |
301 | # Run the method (returns "Hello World!")
302 | say_hello()
303 |
304 | # Define a new method with two arguments
305 | def multiply(first_number, second_number)
306 | first_number * second_number
307 | end
308 |
309 | # Run the method (returns 25)
310 | multiply(5,5)
311 |
312 | ```
313 |
314 |
315 | ## Sinatra
316 |
317 | In Sinatra, there are two primary types of files: Ruby files (ending in `.rb`, only containing Ruby code), and embedded ruby files (ending in `.erb` and combining both HTML and Ruby code). ERB files are usually found in the `app/views/` folder, while Ruby files can usually be found in `app/` or `app/models/`.
318 |
319 |
320 | ### Defining URLs
321 |
322 | To define a new URL in Sinatra, you edit your `app/actions.rb` file. You can add as many URLs as you like, and each one will be visitable in the browser by a site visitor.
323 |
324 | ```ruby
325 | get '/' do
326 | # This code gets run when a user visits "yoursite.com/"
327 | end
328 |
329 | get '/signup' do
330 | # This code gets run when a user visits "yoursite.com/signup"
331 | end
332 | ```
333 |
334 | Using the code above, your site visitor would just see a blank page, because you haven't defined any code to run. If you wanted to render the contents of a particular view file (ERB), you would have to explicitly tell Sinatra to do so. Here's how:
335 |
336 | ```ruby
337 | get '/' do
338 | erb(:homepage) # Sinatra will now render the 'app/views/homepage.erb' file when a user visits 'yoursite.com/'
339 | end
340 | ```
341 |
342 | You can also pass values into your `actions.rb` file by using variables in the URL. When you create variables in the URL, you can then get to them from within Ruby using `params[:variable_name]`, like you do for form data. For instance, perhaps you wanted to edit a particular user. You might want to have unique edit links for each user, so you can pass them around between the various website administrators. Your `actions.rb` file might look like this:
343 |
344 | ```ruby
345 | get '/user/:id/edit` do
346 | # When someone visits "yoursite.com/users/5/edit", the value of "params[:id]" would be "5"
347 | end
348 | ```
349 |
350 |
351 | ### Using a layout
352 |
353 | Often times, websites will have a consistent header and footer that are shown on every page. In Sinatra, the way you accomplish this is by creating a `layout.erb` file. The contents of this file will be displayed on every single page of your app, so that each page has a consistent look and feel. In your `layout.erb` file, you also need to specify where the contents of each page go, and you do that using the `<%= yield %>` tag. Here is a sample layout file:
354 |
355 | ```html
356 |
357 |
358 |
359 |
Super App
360 |
361 |
362 |
363 |
364 |
Super App
365 |
366 |
367 | <%= yield %>
368 |
369 |
370 |
371 | ```
372 |
373 |
374 | ### Instance variables
375 |
376 | Sometimes you need to pass a variable/value to your view file, so that it can display something dynamically. For instance, maybe you want to display a homepage that says "Good morning" or "Good evening" based on the time of day. You would need to pass the time of day into your view file. To do so, you would use an instance variable (one that starts with an `@` sign).
377 |
378 | ```ruby
379 | # Inside your actions.rb file
380 |
381 | get '/' do
382 | @time_of_day = Time.now
383 | erb(:homepage)
384 | end
385 | ```
386 |
387 | ```html
388 |
389 |
390 | The current day and time is: <%= @time_of_day %>
391 | ```
392 |
393 |
394 | ### Partials
395 |
396 | Sometimes in your application, you will want to re-use not only ruby code, but also HTML. The way you create re-usable HTML is by creating partials. A partial is a `.erb` file just like any other, and works exactly the same way. If someone had a weather app, perhaps they would create a single partial that contained today's forecast. Then, each time they wanted to show the forecast, they would just use the partial rather than re-typing all the code. Here's an example:
397 |
398 | ```ruby
399 | # In the actions.rb file
400 |
401 | get '/' do
402 | erb(:homepage)
403 | end
404 |
405 | ```
406 |
407 | ```html
408 |
409 |
410 | <%= erb(:todays_forecast) %>
411 | ```
412 |
413 | ```html
414 |
415 |
416 | The forecast for today is sunny with a chance of meatballs!
417 | ```
418 |
419 | You can get even more complicated with partials and also pass variables into them. For instance, consider the case of a blog website, where comments should always appear in the same format, but the actual text of the comment might change. Here is how you might approach that:
420 |
421 | ```ruby
422 | # In actions.rb
423 |
424 | get '/' do
425 | @comment = "Great post! Really fun to read!"
426 | @commenter = "Joe"
427 | erb(:homepage)
428 | end
429 | ```
430 |
431 | ```html
432 |
433 |
434 | <%= erb(:comment, locals: { text: @comment, name: @commenter }) %>
435 | ```
436 |
437 | ```html
438 |
439 |
440 | <%= name %> says: <%= text %>
441 | ```
442 |
443 |
444 | ### Helper methods
445 |
446 | When you create a method, typically it's only meant for use within your Ruby files. But, Sinatra has a nifty way for you to create methods that you can also use within your view files (ERB). They are called helper methods, and here's how you use them:
447 |
448 | ```ruby
449 | # In actions.rb
450 |
451 | helpers do
452 | def time_of_day
453 | if Time.now.hour < 12
454 | 'morning'
455 | else
456 | 'afternoon'
457 | end
458 | end
459 | end
460 |
461 | get '/' do
462 | erb(:homepage)
463 | end
464 | ```
465 |
466 | ```html
467 |
468 |
469 | Hello there! Welcome and good <%= time_of_day %> to you!
470 | ```
471 |
472 |
473 | ### Form data
474 |
475 | When you want to get user input, you use a form. Sinatra has some fun and helpful ways to let us easily access form data submitted by a user! To start, you define a form in your ERB file, making sure to specify a `method` and an `action`. The method represents _how_ the data will be sent, and the action represents _where_ the data will be sent.
476 |
477 | | Method | Description | When to use |
478 | | ------ | ----------- | ----------- |
479 | | GET | Values appear in the URL | Performing searches or filtering (when you're not "changing" data in your application) |
480 | | POST | Values are sent silently/hidden | Submitting sensitive data, or when the form will change/save something in your application |
481 |
482 | Inside an ERB file, a form would look like this:
483 |
484 | ```html
485 |
491 | ```
492 |
493 | Then, in your `actions.rb` file, you would create a new URL that accepts incoming `POST` requests. Remember, you can access values submitted from a form using `params`, like this:
494 |
495 | ```ruby
496 | post '/signup' do
497 | @name = params[:first_name]
498 | end
499 | ```
500 |
501 |
502 | ### Sessions
503 |
504 | Sessions are a quick and easy way to store data that lasts for more than a single page-load. Remember that anything stored in a session is available for the entire duration of a user's browsing session. We use Ruby to interact with sessions, like so:
505 |
506 | ```ruby
507 | # Set a session value
508 | session[:name] = 'Matt'
509 |
510 | # Get the value of a session (returns "Matt")
511 | session[:name]
512 |
513 | # Clear a session value
514 | session[:name] = nil
515 |
516 | # Clear all session data
517 | session.clear
518 | ```
519 |
520 |
521 | ### Interactive console (tux)
522 |
523 | To start up the interactive console in Sinatra, you type `bundle exec tux` in a terminal (bash) window/tab. If it worked, you should see something like:
524 |
525 | ```
526 | Loading development environment (Rack 1.3)
527 | >>
528 | ```
529 |
530 |
531 | ## ActiveRecord
532 |
533 |
534 | ### Defining a new class/object
535 |
536 | To define a new class/type of object that has a corresponding database table, we create a new `.rb` file in the `app/models/` folder. To make sure the new class has all the ActiveRecord functionality built-in, we let it inherit from `ActiveRecord::Base`, like so:
537 |
538 | ```ruby
539 | class Post < ActiveRecord::Base
540 |
541 | end
542 | ```
543 |
544 | *_Note:_* In the real world, you also need to create the relevant table in the database for this to hook up to. For our course, this was already done when we got started. The scope of how to do this is beyond what's covered in this cheat sheet, but if you're interested in learning more, [this tutorial](https://learn.co/lessons/sinatra-activerecord-setup) offers some insight.
545 |
546 |
547 | ### Built-in methods
548 |
549 | ActiveRecord provides you with a variety of methods that make it easy to interact with your data in the database.
550 |
551 | | Method | Example | Description | Return type |
552 | | ------ | ------- | ----------- | --------- |
553 | | `.find` | `User.find(5)` | Finds the object with the specified ID | Single object |
554 | | `.where` | `User.where(name: 'Matt')` | Finds the objects that match the filters you provided (i.e. where the name is "Matt") | Array of objects |
555 | | `.first` | `User.first` | Gets the first object in the database table | Single object |
556 | | `.last` | `User.last` | Gets the last object in the database table | Single object |
557 | | `.new` | `User.new(name: 'Matt')` | Creates a new instance of the user class (doesn't save to the database) | Single object |
558 | | `.create` | `User.create(name: 'Matt')` | Creates and *saves* a new instance of the user class to the database (you know it's saved because it will have an ID) | Single object |
559 | | `.save` | `User.new(name: 'Matt').save` | Saves your changes to the database | `true`/`false` |
560 |
561 |
562 |
563 | ### Defining relationships
564 |
565 | In an application with multiple classes/models, you will usually have relationships between them. Consider the example of a `Post` belonging to a `User`. Here is how you would specify those relationships in your classes/models:
566 |
567 | ```ruby
568 | class User < ActiveRecord::Base
569 | has_many :posts
570 | end
571 |
572 | class Post < ActiveRecord::Base
573 | belongs_to :user
574 | end
575 | ```
576 |
577 | Once you have the association setup, you can then easily get a lists of all the posts that a user has created by doing something like this:
578 |
579 | ```ruby
580 | # Find a user
581 | user = User.find(5)
582 |
583 | # Get a list of all the posts by that user
584 | user.posts
585 |
586 | # We can also do it the opposite way... start by finding a post
587 | post = Post.find(12)
588 |
589 | # What user made this post?
590 | post.user
591 | ```
592 |
593 |
594 | ### Model validations
595 |
596 | ActiveRecord provides us with convenient ways to add validations to our classes/models. When a validation is in place, a new record in the database cannot be created, edited or saved unless it passes all of our validations! To define a validation, you specify it on the model/class:
597 |
598 | ```ruby
599 | class User < ActiveRecord::Base
600 |
601 | # Every user must have a name and an email
602 | validates_presence_of :name, :email
603 |
604 | # The same email can't belong to multiple users
605 | validates_uniqueness_of :email
606 |
607 | end
608 | ```
609 |
610 | To check if a particular instance of the `User` class passes validation, you could try creating a new one, then use the `.valid?` method (which returns `true`/`false`). Here is what you might do after someone submits a signup form:
611 |
612 | ```ruby
613 | # In actions.rb
614 |
615 | post '/signup' do
616 |
617 | name = params[:name]
618 | email = params[:email]
619 |
620 | @user = User.new(name: name, email: email)
621 |
622 | if @user.save # Calling .save automatically runs validations!
623 | erb(:signup_success)
624 | else
625 | erb(:signup_failed)
626 | end
627 |
628 | end
629 | ```
630 |
631 | _For a full list of all possible built-in validations, refer to [this guide](http://guides.rubyonrails.org/active_record_validations.html)._
632 |
633 |
634 | ### Updating values
635 |
636 | The web isn't static, which necessitates having the ability to edit data after you've saved it to the database! With ActiveRecord, this is super easy! Let's say you wanted to update the name and address for a user in your database. You would start by locating their user ID, open up `bundle exec tux`, and then do the following:
637 |
638 | ```ruby
639 | user = User.find(5)
640 | user.name = 'New Name'
641 | user.address = 'New Address'
642 | user.save
643 | ```
644 |
645 |
646 | ## Git
647 |
648 | When performing Git operations, you do them from within the `bash` window. In the majority of cases, when you're done working on the code for a particular set of features, you will do the following:
649 |
650 | **Step 1:** Check file status
651 | ```
652 | git status
653 | ```
654 |
655 | **Step 2:** Stage your files (prepare them to be committed)
656 | ```
657 | git add .
658 | ```
659 |
660 | **Step 3:** Commit your changes
661 | ```
662 | git commit -m "Description of your changes."
663 | ```
664 |
665 | **Step 4:** Push your changes to GitHub
666 | ```
667 | git push origin master
668 | ```
669 |
670 |
671 | ## Heroku
672 |
673 | Details on pushing to Heroku and updating your app with new changes can be found [in this guide](https://gist.github.com/matt297/dfc9a2c7e6c13516a767879f2ceb724e).
674 |
--------------------------------------------------------------------------------