├── 01-todo_app_intro └── README.md ├── 02-todo_app_styling └── README.md ├── 03-todo_ujs_haml_coffee └── README.txt ├── 2015-10-27-introduction-to-sorting-algorithms ├── insertion_sort.rb ├── merge_sort.rb └── quick_sort.rb ├── 2015-11-3-introduction-to-graphs ├── dijkstra.rb └── visit_graph.rb ├── 2016-1-26-learn-the-swift-toolbox └── Swift Toolbox slides.pdf ├── 2016-10-25-reactive-programming └── Let's try Reactive programming.pdf ├── 2016-2-23-kotlin-tour └── Kotlin Tour.pdf ├── 2016-9-13-coding-interview └── Preparing the coding interview.pdf ├── 2016-9-6-git-branching └── The Art of Git branching.pdf ├── LICENSE ├── apis └── api_lesson │ ├── .gitignore │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.rdoc │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── images │ │ │ └── .keep │ │ ├── javascripts │ │ │ ├── application.js │ │ │ └── players.coffee │ │ └── stylesheets │ │ │ ├── application.css │ │ │ ├── players.scss │ │ │ └── scaffolds.scss │ ├── controllers │ │ ├── api │ │ │ ├── api_controller.rb │ │ │ └── v1 │ │ │ │ └── players_controller.rb │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── players_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── players_helper.rb │ ├── mailers │ │ └── .keep │ ├── models │ │ ├── .keep │ │ ├── concerns │ │ │ └── .keep │ │ └── player.rb │ └── views │ │ ├── layouts │ │ └── application.html.erb │ │ └── players │ │ ├── _form.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── index.json.jbuilder │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ └── show.json.jbuilder │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ └── spring │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── session_store.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── routes.rb │ └── secrets.yml │ ├── db │ ├── migrate │ │ └── 20150708021926_create_players.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ └── .keep │ ├── log │ └── .keep │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── robots.txt │ └── vendor │ └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep └── swift-walkthrough ├── part1.md └── part2.md /01-todo_app_intro/README.md: -------------------------------------------------------------------------------- 1 | # TODO App 2 | 3 | A Ruby on Rails application to keep track of TODO items. 4 | Created in RailsSchool. 5 | 6 | - [RailsSchool Lesson](http://www.railsschool.org/l/todo-create-your-first-ruby-on-rails-app) (includes whiteboard) 7 | - [Completed Code](https://github.com/rails-school/todo_app_lesson01) 8 | 9 | ## Lesson Outline 10 | 11 | 1. Create a new nitrous.io environment - If you've followed the [FAQ](http://www.railsschool.org/faq) and created a local development environment, this works too, but we've found beginners are more comfortable using nitrous.io 12 | 13 | 1. Go over what we want to do - create an application to track To Do items (how meta...) 14 | 15 | 1. Create a new rails app in the console (It's that space on the bottom that ends in a `$`, so we'll use a `$` to indicate commands that you should run in the console) 16 | 17 | $ rails new todos_app 18 | 19 | 4. Change Directory to the newly created todos_app directory 20 | 21 | $ cd todos_app 22 | 23 | 5. Use rails built-in scaffolds to add the idea of a to do that we can check off 24 | 25 | $ rails generate scaffold todo title:string description:text is_complete:boolean 26 | 27 | 6. This scaffolding created a database migration that needs to be run, so run it with 28 | 29 | $ rake db:create 30 | $ rake db:migrate 31 | 32 | 7. Launch the rails server 33 | 34 | $ rails server 35 | 36 | 8. Preview the application by clicking on **Preview → Port 3000** 37 | 38 | 9. You should see the default welcome to rails screen. Browse to `/todos` to see the todo scaffold. 39 | 40 | 10. We want the todos scaffold to be our root page, so in the editor, open `config/routes.rb` and add following line inside the `do...end` block: 41 | 42 | root 'todos#index' 43 | 44 | 11. Browse to the root page (or click **Preview → Port 3000** again) and play around. Notice that we didn't have to restart our rails server. 45 | 46 | ## Extra 47 | 48 | We had some time left over, so we decided to add another field to our Todo model in order to keep track of when we want to accomplish our todo items. 49 | 50 | 1. add new field to track when the todo item is due (note: you can create a new console tab for this, just remember to `cd todos_app`): 51 | 52 | $ rails generate migration add_due_at_to_todos due_at:datetime 53 | $ rake db:migrate 54 | 55 | 1. Enter the console to set the `due_at` fields for some existing todos: 56 | 57 | $ rails console 58 | > t = Todo.find(1) 59 | > t.due_at = "2014-09-05" 60 | > t.save! 61 | > t = Todo.find(2) 62 | > t.due_at = 5.days.from_now 63 | > t.save! 64 | 65 | 1. Edit `app/views/todos/index.html.erb` to show the `due_at` field: 66 | 67 | 1. edit app/views/todos/_form.html.erb to add the due_at field to our form 68 | 69 |
70 | <%= f.label :due_at %>
71 | <%= f.date_select :due_at %> 72 |
73 | 74 | 1. tell the controller to allow the `due_at` field in the params 75 | 76 | def todo_params 77 | params.require(:todo).permit(:title, :description, :is_completed, :due_at) 78 | end 79 | 80 | 81 | ## Tips & Tricks 82 | 83 | - While we can make changes to `config/routes.rb` or the files in `app/` without having to restart the rails server, if you want to restart it, in the console, press `Ctrl+c` (while holding down the `CTRL` key, press the `C` key) to quit out of the running server, and then press the up arrow (or retype `rails server`) and hit enter to relaunch the server. 84 | 85 | - `rails s` works as shorthand for `rails server` 86 | 87 | - `rails g` works as shorthand for `rails generate` 88 | 89 | - When in the console, you don't have to type out full names of files and directories. Just start typing and then hit the `TAB` key to autocomplete. This is known as __Tab Completion__. For example `$ cd tod[TAB]` will autocomplete to `$ cd todo_app` if you're in a new console. 90 | 91 | - When in the `rails console`, if you change a file in `app/`, type `reload!` to grab those changes so you don't have to restart the rails console. 92 | 93 | -------------------------------------------------------------------------------- /02-todo_app_styling/README.md: -------------------------------------------------------------------------------- 1 | # Styling our ToDo App 2 | 3 | In this lesson we're going to take what we built last week and make it look much nicer. Don't worry if you missed last week, as we'll show you how to grab the code from last week. 4 | 5 | ## Lesson Outline 6 | 7 | 1. If you still have your nitrous.io instance from last week, and your code is up to date, you can skip this step. Otherwise, 8 | 9 | 1. Create a [nitrous.io](nitrous.io) instance to run Ruby on Rails 10 | 11 | 1. If you already have an instance but want to start fresh, then delete the folder you created last time 12 | 13 | $ rm -rf todo_app 14 | 15 | 1. Pull the code from lesson01 into your nitrous box 16 | 17 | $ git clone https://github.com/rails-school/todo_app_lesson01.git 18 | 19 | - (optional, advanced) try forking the github repository and then cloning your fork so you can push your changes back to it. 20 | 21 | 1. Initialize the rails app and make sure you can Preview it on Port 3000 (and create a new todo) 22 | 23 | $ cd todo_app_lesson01 24 | $ bundle install 25 | $ rake db:create 26 | $ rake db:migrate 27 | $ rails server 28 | 29 | 1. Introduction to CSS 30 | 31 | 1. with your `rails server` running, preview the server in Chrome (these instructions target chrome, but you can also do almost the same thing in Firefox. Safari and IE have developer tools as well.) 32 | 33 | 1. right click on a todo item and choose __Inspect Element__ to open up the developer tools. 34 | 35 | 1. In the styles panel, play around with the settings to change the apperance of the item 36 | 37 | 1. Hardcoding CSS 38 | 39 | 1. Remember the styles we just figured out? We can enter them into `app/assets/stylesheets/application.css` 40 | 41 | 1. But that gets messy, so lets put them into `app/assets/stylesheets/custom.css` and require that file from `application.css` 42 | 43 | 1. Getting Some Sass 44 | 45 | 1. To make our lives easier, we can add some functionality to css, like support for variables and nested styles. To do this, change `application.css` to `aplication.css.scss` to indicate that rails should _preprocess_ the file with the `scss` preprocessor. 46 | 47 | 1. Create a file `app/assets/stylesheets/_variables.css.scss` and define some variables, like: 48 | 49 | $main-color: blue; 50 | 51 | 1. Now in `app/assets/stylesheets/application.css.scss` get rid of the `require_tree` directive, and explicitly import our variables, so that they're available to all our stylesheets. Also let's import our `custom` definitions rather than require them. 52 | 53 | /* 54 | *= require_self 55 | */ 56 | 57 | @import 'variables'; 58 | @import 'custom'; 59 | 60 | 1. rename `custom.css` to `_custom.css.scss` 61 | 62 | 1. Now feel free to use our variables inside `_custom.css.scss` 63 | 64 | 1. Now that we have an understanding of css and sass, we're going to take things to the next level by adding some convenience libraries. Add the following to the `Gemfile`: 65 | 66 | gem 'bourbon' 67 | gem 'neat' 68 | gem 'bitters' 69 | gem 'refills' 70 | 71 | 1. Install these gems 72 | 73 | $ bundle install 74 | 75 | 1. Install the styles that come with _bitters_ 76 | 77 | $ cd app/assets/stylesheets 78 | $ bitters install 79 | 80 | 1. reference all these new goodies in our `application.css.scss` 81 | 82 | @import "bourbon"; 83 | @import "base/base"; 84 | @import "neat"; 85 | 86 | 1. Since we're using both _neat_ and _bitters_ we have to uncomment the following line in `app/assets/stylesheets/base/_base.scss`: 87 | 88 | @import "grid-settings"; 89 | 90 | 1. Refresh the web page and notice that it's already starting to look better! 91 | 92 | 1. Dive deeper into styling. 93 | 94 | 1. First, let's go over the _neat_ grid layout at http://neat.bourbon.io/examples/ 95 | 96 | 1. Play around with layouts and styling, using the _neat_ grid as well as available [Bourbon](http://bourbon.io/docs/) mixins. 97 | 98 | 1. Use some rich existing layouts 99 | 100 | 1. Check out the components that we can grab from [Refills](http://refills.bourbon.io/) 101 | 102 | 1. You can either copy + paste the html and styling from this website, or because we installed the `refills` gem, you can view available refills with: 103 | 104 | $ rails g refills:list 105 | 106 | 1. Once you find one you want to use, install it. In this case, I want to make our todo items look like cards. 107 | 108 | 1. Install the html and styling 109 | 110 | $ rails g refills:import cards 111 | 112 | 1. Include it into our `application.css.scss` 113 | 114 | @import 'refills/cards'; 115 | 116 | 1. Include it into our web page by copying and pasting the created `app/views/refills/cards.html.erb` into our `app/views/todos/index.html.erb` 117 | 118 | 1. Repeat with other components. For example, say we wanted a landing page with a big hero message: 119 | 120 | 1. Create a new `home_controller.rb` controller, with a single empty `index` method. 121 | 122 | 1. Create the directory `app/views/home` and add a file `index.html.erb` in it. 123 | 124 | 1. Update the root controller/action in `config/routes.rb` to point to `home#index` 125 | 126 | 1. Install the html and styling 127 | 128 | $ rails g refills:import hero 129 | 130 | 1. Include it in our `application.css.scss` 131 | 132 | @import 'refills/hero'; 133 | 134 | 1. Copy `app/views/refills/hero.html.erb` into the newly created `app/views/home/index.html.erb` 135 | -------------------------------------------------------------------------------- /03-todo_ujs_haml_coffee/README.txt: -------------------------------------------------------------------------------- 1 | (copied from whiteboard, not formatted yet) 2 | 3 | Haml: http://haml.info/ 4 | Haml Reference: http://haml.info/docs/yardoc/file.REFERENCE.html 5 | Converter: http://htmltohaml.com/ 6 | 7 | Coffeescript: http://coffeescript.org/ (can try out coffee -> javascript here) 8 | js2coffee for converting existing javascript to coffeescript (or the other way): http://js2coffee.org/ 9 | 10 | Editor: spaces vs. tabs 11 | Because haml and coffeescript both give meaning to indentation, it's important to set your editor to use spaces instead of tabs. 12 | 13 | In Sublime, go to Preferences -> Settigns - Default, and set "translate_tabs_to_spaces": true, 14 | nitrous.io uses the correct settings already 15 | 16 | 17 | Notes: 18 | go to nitrous.io and fire up a rails dev box, or use your local dev machine if you have one set up. 19 | $ rails new todos 20 | $ cd todos 21 | 22 | add to Gemfile: 23 | gem 'haml-rails' 24 | $ bundle install 25 | 26 | scaffold our Todo model, controller, and views 27 | $ rails g scaffold todo title:string is_completed:boolean 28 | rake db:create 29 | rake db:migrate 30 | 31 | add to config/routes.rb: 32 | root 'todos#index' 33 | 34 | 35 | rename app/views/layouts/application.html.erb to application.html.haml and switch its contents to the haml equivalent: 36 | 37 | !!! 5 38 | %html 39 | %head 40 | %title Todos 41 | = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true 42 | = javascript_include_tag 'application', 'data-turbolinks-track' => true 43 | = csrf_meta_tags 44 | %body 45 | = yield 46 | 47 | The following are all the other files we changed/created. We didn't do them all at once, but rather built up. We started by having index.html.haml just have a remote link, and then created new.js.coffee to test that remote link. Initially, we just had new.js.coffee be something simple like: alert("new todo clicked") to ensure that it was being run, then we switched it to use jquery to insert some text into the index.html.haml (we also created a div to stick that text into), and then finally we rendered a form as the text, and escaped it so that it could fit into a javascript string. 48 | 49 | 50 | app/views/ 51 | 52 | index.html.haml 53 | 54 | %h1 Listing todos 55 | #todos-list 56 | = render @todos 57 | = link_to 'New Todo', new_todo_path, remote: true 58 | #new-todo-form 59 | 60 | 61 | form.html.haml - we just changed line 1 to make it a remote form 62 | 63 | = form_for @todo, remote: true do |f| 64 | 65 | 66 | _todo.html.haml - we created this partial, which is used to render each todo in the collection when we render @todos 67 | 68 | - if todo.is_completed 69 | .title.completed= todo.title 70 | - else 71 | .title= todo.title 72 | = form_for(todo, remote: true) do |f| 73 | = f.hidden_field :is_completed, value: true 74 | = f.submit '✓' 75 | 76 | 77 | new.js.coffee - show the new todo form as a result of clicking 'New Todo' 78 | 79 | $("#new-todo-form").html("<%= j(render 'form') %>") 80 | $("#todo_title").focus() 81 | 82 | 83 | create.js.coffee - refresh the list of todos as a result of submitting the new todo form. We took a shortcut and used this also as a result of updating a todo. We also demonstrated a little bit of coffeescript for a small easter egg here: 84 | 85 | $("#todos-list").html("<%= j(render @todos) %>") 86 | $("#new-todo-form").html("") 87 | $(".title").each (idx, elem)-> 88 | $(elem).css("background-color", "green") if $(elem).html() == "Learn Coffeescript" 89 | 90 | 91 | app/controllers/todos_controller.rb - in both create and update, add the following: 92 | 93 | @todos = Todo.all 94 | format.js { render :create } 95 | 96 | 97 | app/assets/stylesheets/todos.css.scss - we added a tiny bit of style to the list 98 | 99 | .title { 100 | font-weight: bold; 101 | float: left; 102 | margin-right: 1em; 103 | &.completed { 104 | text-decoration: line-through; 105 | float: none; 106 | } 107 | &.completed:after { 108 | content: "✓"; 109 | } 110 | } 111 | 112 | -------------------------------------------------------------------------------- /2015-10-27-introduction-to-sorting-algorithms/insertion_sort.rb: -------------------------------------------------------------------------------- 1 | def swap(a, i, j) 2 | tmp = a[i] 3 | a[i] = a[j] 4 | a[j] = tmp 5 | end 6 | 7 | def sort(a) 8 | i = 0 9 | 10 | while i < a.length 11 | j = i + 1 12 | min = a[i] 13 | k = i 14 | while j < a.length 15 | if a[j] < min 16 | min = a[j] 17 | k = j 18 | end 19 | j += 1 20 | end 21 | 22 | swap(a, i, k) 23 | i += 1 24 | end 25 | 26 | a 27 | end 28 | 29 | sort [45, 89, 14, 13598, 1487, 2, 3, 568, 81] -------------------------------------------------------------------------------- /2015-10-27-introduction-to-sorting-algorithms/merge_sort.rb: -------------------------------------------------------------------------------- 1 | def swap(a, i, j) 2 | tmp = a[i] 3 | a[i] = a[j] 4 | a[j] = tmp 5 | end 6 | 7 | def sort_rec(a, i_start, i_end) 8 | if i_start == i_end 9 | return [a[i_start]] 10 | elsif i_start == i_end - 1 11 | if a[i_start] > a[i_end] 12 | return [a[i_end], a[i_start]] 13 | else 14 | return [a[i_start], a[i_end]] 15 | end 16 | else 17 | middle = (i_end + i_start) / 2 18 | t = sort_rec(a, i_start, middle) 19 | u = sort_rec(a, middle + 1, i_end) 20 | k = 0 21 | l = 0 22 | outcome = [] 23 | 24 | while k < t.count && l < u.count 25 | if t[k] < u[l] 26 | outcome << t[k] 27 | k += 1 28 | else 29 | outcome << u[l] 30 | l += 1 31 | end 32 | end 33 | 34 | if l >= u.count 35 | while k < t.count 36 | outcome << t[k] 37 | k += 1 38 | end 39 | else 40 | while l < u.count 41 | outcome << u[l] 42 | l += 1 43 | end 44 | end 45 | 46 | return outcome 47 | end 48 | end 49 | 50 | def sort(a) 51 | sort_rec(a, 0, a.count - 1) 52 | end 53 | 54 | sort [45, 89, 14, 13598, 1487, 2, 3, 568, 81] -------------------------------------------------------------------------------- /2015-10-27-introduction-to-sorting-algorithms/quick_sort.rb: -------------------------------------------------------------------------------- 1 | def swap(a, i, j) 2 | tmp = a[i] 3 | a[i] = a[j] 4 | a[j] = tmp 5 | end 6 | 7 | def partition(a, i_start, i_end, i_pivot) 8 | swap(a, i_end, i_pivot) 9 | i_pivot = i_end 10 | 11 | i = i_start 12 | j = i_start 13 | while i < i_end 14 | if a[i] < a[i_pivot] 15 | swap(a, i, j) 16 | j += 1 17 | end 18 | i += 1 19 | end 20 | 21 | swap(a, j, i_pivot) 22 | j 23 | end 24 | 25 | def quick_sort_rec(a, i_start, i_end) 26 | if i_start < i_end 27 | pivot = i_start 28 | p = partition a, i_start, i_end, pivot 29 | quick_sort_rec a, i_start, p - 1 30 | quick_sort_rec a, p + 1, i_end 31 | end 32 | end 33 | 34 | def sort(a) 35 | quick_sort_rec(a, 0, a.count - 1) 36 | a 37 | end 38 | 39 | sort [45, 89, 14, 13598, 1487, 2, 3, 568, 81] -------------------------------------------------------------------------------- /2015-11-3-introduction-to-graphs/dijkstra.rb: -------------------------------------------------------------------------------- 1 | class Vertex 2 | def initialize(id) 3 | @id = id 4 | @neighbors = [] 5 | end 6 | 7 | def id 8 | @id 9 | end 10 | 11 | def neighbors 12 | @neighbors 13 | end 14 | 15 | def ==(other) 16 | @id == other.id 17 | end 18 | end 19 | 20 | class Edge 21 | def initialize(source, dest, length) 22 | @source = source 23 | @dest = dest 24 | @length = length 25 | end 26 | 27 | def source 28 | @source 29 | end 30 | 31 | def dest 32 | @dest 33 | end 34 | 35 | def length 36 | @length 37 | end 38 | end 39 | 40 | class Graph 41 | def initialize() 42 | @vertices = [] 43 | @edges = [] 44 | end 45 | 46 | def vertices 47 | @vertices 48 | end 49 | 50 | def length(source, dest) 51 | @edges.each do |e| 52 | if e.source == source && e.dest == dest 53 | return e.length 54 | end 55 | end 56 | 57 | 0 58 | end 59 | 60 | # Create an edge between source and dest 61 | def tie(source, dest, length) 62 | @vertices << source unless @vertices.include? source 63 | source.neighbors << dest 64 | @vertices << dest unless @vertices.include? dest 65 | @edges << Edge.new(source, dest, length) 66 | end 67 | end 68 | 69 | # Data object returned after running Dijkstra 70 | class DijkstraResult 71 | def initialize(source, dest, dist, prev) 72 | @distance = dist[dest.id] 73 | @path = [] 74 | build_path prev, source, dest 75 | end 76 | 77 | def distance 78 | @distance 79 | end 80 | 81 | # Returns the path from source to dest 82 | def path 83 | @path 84 | end 85 | 86 | private 87 | 88 | # Builds path using the prev associative array 89 | def build_path(prev, source, current) 90 | @path = [current.id] + @path 91 | return if source == current 92 | build_path prev, source, prev[current.id] 93 | end 94 | end 95 | 96 | $MAX_VAL = 99999999 97 | 98 | # Returns the closest node to source 99 | def min_to_source(dist, prev, source, vertices) 100 | def min_to_source_aux(dist, prev, source, vertex) 101 | return $MAX_VAL if vertex.nil? # Hasn't been visited yet 102 | return 0 if vertex == source 103 | return dist[vertex.id] + min_to_source_aux(dist, prev, source, prev[vertex.id]) 104 | end 105 | 106 | min = nil 107 | current_vertex = nil 108 | vertices.each do |v| 109 | value = min_to_source_aux(dist, prev, source, v) 110 | if min.nil? || value < min 111 | min = value 112 | current_vertex = v 113 | end 114 | end 115 | 116 | return current_vertex 117 | end 118 | 119 | def dijkstra(graph, source, dest) 120 | default_dist = $MAX_VAL 121 | dist = {} # Matches node to its distance to the source 122 | prev = {} # Matches node with its predecessor (in the shortest path) 123 | vertex_set = [] # Nodes that have not been visited yet 124 | 125 | # Initialize the different structures 126 | graph.vertices.each do |v| 127 | if v == source 128 | dist[v.id] = 0 129 | else 130 | dist[v.id] = default_dist 131 | end 132 | 133 | prev[v.id] = nil 134 | vertex_set << v 135 | end 136 | 137 | current_vertex = nil 138 | while vertex_set.length > 0 139 | if current_vertex.nil? 140 | current_vertex = source 141 | else 142 | current_vertex = min_to_source(dist, prev, current_vertex, vertex_set) 143 | end 144 | vertex_set.delete current_vertex 145 | 146 | current_vertex.neighbors.each do |v| 147 | alternative = dist[current_vertex.id] + graph.length(current_vertex, v) 148 | if alternative < dist[v.id] # A better route has been found 149 | dist[v.id] = alternative 150 | prev[v.id] = current_vertex 151 | end 152 | end 153 | end 154 | 155 | DijkstraResult.new source, dest, dist, prev 156 | end 157 | 158 | a = Vertex.new('A') 159 | b = Vertex.new('B') 160 | c = Vertex.new('C') 161 | d = Vertex.new('D') 162 | e = Vertex.new('E') 163 | f = Vertex.new('F') 164 | 165 | graph = Graph.new 166 | graph.tie a, b, 5 167 | graph.tie a, c, 3 168 | graph.tie b, d, 15 169 | graph.tie b, e, 8 170 | graph.tie c, d, 45 171 | graph.tie c, e, 2 172 | graph.tie d, f, 10 173 | graph.tie e, d, 4 174 | graph.tie e, f, 60 175 | 176 | result = dijkstra graph, a, f 177 | print("#{result.distance} - #{result.path}\n") -------------------------------------------------------------------------------- /2015-11-3-introduction-to-graphs/visit_graph.rb: -------------------------------------------------------------------------------- 1 | class Graph 2 | attr_accessor :start 3 | 4 | def initialize(start) 5 | @start = start 6 | end 7 | end 8 | 9 | class Vertex 10 | attr_accessor :identifier 11 | attr_accessor :neighbors 12 | 13 | def initialize(identifier) 14 | @identifier = identifier 15 | @color = 0 16 | end 17 | 18 | def white? 19 | @color == 0 20 | end 21 | 22 | def gray? 23 | @color == 1 24 | end 25 | 26 | def black? 27 | @color == 2 28 | end 29 | 30 | def set_gray 31 | @color = 1 32 | end 33 | 34 | def set_black 35 | @color = 2 36 | end 37 | end 38 | 39 | def visit_graph(graph) 40 | def visit_vertex(v) 41 | v.set_gray 42 | v.neighbors.each do |n| 43 | visit_vertex(n) if n.white? 44 | end 45 | v.set_black 46 | puts v.identifier 47 | end 48 | 49 | visit_vertex graph.start 50 | end 51 | 52 | a = Vertex.new 'A' 53 | b = Vertex.new 'B' 54 | c = Vertex.new 'C' 55 | d = Vertex.new 'D' 56 | e = Vertex.new 'E' 57 | f = Vertex.new 'F' 58 | 59 | a.neighbors = [b, c] 60 | b.neighbors = [a, d, e] 61 | c.neighbors = [a, d, e] 62 | d.neighbors = [b, c, e, f] 63 | e.neighbors = [b, c, d, f] 64 | f.neighbors = [d, e] 65 | 66 | g = Graph.new a 67 | visit_graph g -------------------------------------------------------------------------------- /2016-1-26-learn-the-swift-toolbox/Swift Toolbox slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/2016-1-26-learn-the-swift-toolbox/Swift Toolbox slides.pdf -------------------------------------------------------------------------------- /2016-10-25-reactive-programming/Let's try Reactive programming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/2016-10-25-reactive-programming/Let's try Reactive programming.pdf -------------------------------------------------------------------------------- /2016-2-23-kotlin-tour/Kotlin Tour.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/2016-2-23-kotlin-tour/Kotlin Tour.pdf -------------------------------------------------------------------------------- /2016-9-13-coding-interview/Preparing the coding interview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/2016-9-13-coding-interview/Preparing the coding interview.pdf -------------------------------------------------------------------------------- /2016-9-6-git-branching/The Art of Git branching.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/2016-9-6-git-branching/The Art of Git branching.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Rails School San Francisco 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /apis/api_lesson/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | -------------------------------------------------------------------------------- /apis/api_lesson/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | 4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 5 | gem 'rails', '4.2.2' 6 | # Use sqlite3 as the database for Active Record 7 | gem 'sqlite3' 8 | # Use SCSS for stylesheets 9 | gem 'sass-rails', '~> 5.0' 10 | # Use Uglifier as compressor for JavaScript assets 11 | gem 'uglifier', '>= 1.3.0' 12 | # Use CoffeeScript for .coffee assets and views 13 | gem 'coffee-rails', '~> 4.1.0' 14 | # See https://github.com/rails/execjs#readme for more supported runtimes 15 | # gem 'therubyracer', platforms: :ruby 16 | 17 | # Use jquery as the JavaScript library 18 | gem 'jquery-rails' 19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 20 | gem 'turbolinks' 21 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 22 | gem 'jbuilder', '~> 2.0' 23 | # bundle exec rake doc:rails generates the API under doc/api. 24 | gem 'sdoc', '~> 0.4.0', group: :doc 25 | 26 | # Use ActiveModel has_secure_password 27 | # gem 'bcrypt', '~> 3.1.7' 28 | 29 | # Use Unicorn as the app server 30 | # gem 'unicorn' 31 | 32 | # Use Capistrano for deployment 33 | # gem 'capistrano-rails', group: :development 34 | 35 | group :development, :test do 36 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 37 | gem 'byebug' 38 | 39 | # Access an IRB console on exception pages or by using <%= console %> in views 40 | gem 'web-console', '~> 2.0' 41 | 42 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 43 | gem 'spring' 44 | end 45 | 46 | -------------------------------------------------------------------------------- /apis/api_lesson/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.2.2) 5 | actionpack (= 4.2.2) 6 | actionview (= 4.2.2) 7 | activejob (= 4.2.2) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 1.0, >= 1.0.5) 10 | actionpack (4.2.2) 11 | actionview (= 4.2.2) 12 | activesupport (= 4.2.2) 13 | rack (~> 1.6) 14 | rack-test (~> 0.6.2) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 17 | actionview (4.2.2) 18 | activesupport (= 4.2.2) 19 | builder (~> 3.1) 20 | erubis (~> 2.7.0) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 23 | activejob (4.2.2) 24 | activesupport (= 4.2.2) 25 | globalid (>= 0.3.0) 26 | activemodel (4.2.2) 27 | activesupport (= 4.2.2) 28 | builder (~> 3.1) 29 | activerecord (4.2.2) 30 | activemodel (= 4.2.2) 31 | activesupport (= 4.2.2) 32 | arel (~> 6.0) 33 | activesupport (4.2.2) 34 | i18n (~> 0.7) 35 | json (~> 1.7, >= 1.7.7) 36 | minitest (~> 5.1) 37 | thread_safe (~> 0.3, >= 0.3.4) 38 | tzinfo (~> 1.1) 39 | arel (6.0.0) 40 | binding_of_caller (0.7.2) 41 | debug_inspector (>= 0.0.1) 42 | builder (3.2.2) 43 | byebug (5.0.0) 44 | columnize (= 0.9.0) 45 | coffee-rails (4.1.0) 46 | coffee-script (>= 2.2.0) 47 | railties (>= 4.0.0, < 5.0) 48 | coffee-script (2.4.1) 49 | coffee-script-source 50 | execjs 51 | coffee-script-source (1.9.1.1) 52 | columnize (0.9.0) 53 | debug_inspector (0.0.2) 54 | erubis (2.7.0) 55 | execjs (2.5.2) 56 | globalid (0.3.5) 57 | activesupport (>= 4.1.0) 58 | i18n (0.7.0) 59 | jbuilder (2.3.1) 60 | activesupport (>= 3.0.0, < 5) 61 | multi_json (~> 1.2) 62 | jquery-rails (4.0.4) 63 | rails-dom-testing (~> 1.0) 64 | railties (>= 4.2.0) 65 | thor (>= 0.14, < 2.0) 66 | json (1.8.3) 67 | loofah (2.0.2) 68 | nokogiri (>= 1.5.9) 69 | mail (2.6.3) 70 | mime-types (>= 1.16, < 3) 71 | mime-types (2.6.1) 72 | mini_portile (0.6.2) 73 | minitest (5.7.0) 74 | multi_json (1.11.2) 75 | nokogiri (1.6.6.2) 76 | mini_portile (~> 0.6.0) 77 | rack (1.6.4) 78 | rack-test (0.6.3) 79 | rack (>= 1.0) 80 | rails (4.2.2) 81 | actionmailer (= 4.2.2) 82 | actionpack (= 4.2.2) 83 | actionview (= 4.2.2) 84 | activejob (= 4.2.2) 85 | activemodel (= 4.2.2) 86 | activerecord (= 4.2.2) 87 | activesupport (= 4.2.2) 88 | bundler (>= 1.3.0, < 2.0) 89 | railties (= 4.2.2) 90 | sprockets-rails 91 | rails-deprecated_sanitizer (1.0.3) 92 | activesupport (>= 4.2.0.alpha) 93 | rails-dom-testing (1.0.6) 94 | activesupport (>= 4.2.0.beta, < 5.0) 95 | nokogiri (~> 1.6.0) 96 | rails-deprecated_sanitizer (>= 1.0.1) 97 | rails-html-sanitizer (1.0.2) 98 | loofah (~> 2.0) 99 | railties (4.2.2) 100 | actionpack (= 4.2.2) 101 | activesupport (= 4.2.2) 102 | rake (>= 0.8.7) 103 | thor (>= 0.18.1, < 2.0) 104 | rake (10.4.2) 105 | rdoc (4.2.0) 106 | sass (3.4.15) 107 | sass-rails (5.0.3) 108 | railties (>= 4.0.0, < 5.0) 109 | sass (~> 3.1) 110 | sprockets (>= 2.8, < 4.0) 111 | sprockets-rails (>= 2.0, < 4.0) 112 | tilt (~> 1.1) 113 | sdoc (0.4.1) 114 | json (~> 1.7, >= 1.7.7) 115 | rdoc (~> 4.0) 116 | spring (1.3.6) 117 | sprockets (3.2.0) 118 | rack (~> 1.0) 119 | sprockets-rails (2.3.2) 120 | actionpack (>= 3.0) 121 | activesupport (>= 3.0) 122 | sprockets (>= 2.8, < 4.0) 123 | sqlite3 (1.3.10) 124 | thor (0.19.1) 125 | thread_safe (0.3.5) 126 | tilt (1.4.1) 127 | turbolinks (2.5.3) 128 | coffee-rails 129 | tzinfo (1.2.2) 130 | thread_safe (~> 0.1) 131 | uglifier (2.7.1) 132 | execjs (>= 0.3.0) 133 | json (>= 1.8.0) 134 | web-console (2.1.3) 135 | activemodel (>= 4.0) 136 | binding_of_caller (>= 0.7.2) 137 | railties (>= 4.0) 138 | sprockets-rails (>= 2.0, < 4.0) 139 | 140 | PLATFORMS 141 | ruby 142 | 143 | DEPENDENCIES 144 | byebug 145 | coffee-rails (~> 4.1.0) 146 | jbuilder (~> 2.0) 147 | jquery-rails 148 | rails (= 4.2.2) 149 | sass-rails (~> 5.0) 150 | sdoc (~> 0.4.0) 151 | spring 152 | sqlite3 153 | turbolinks 154 | uglifier (>= 1.3.0) 155 | web-console (~> 2.0) 156 | 157 | BUNDLED WITH 158 | 1.10.4 159 | -------------------------------------------------------------------------------- /apis/api_lesson/README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /apis/api_lesson/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/app/assets/images/.keep -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require turbolinks 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/javascripts/players.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/stylesheets/players.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the players controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /apis/api_lesson/app/assets/stylesheets/scaffolds.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fff; 3 | color: #333; 4 | font-family: verdana, arial, helvetica, sans-serif; 5 | font-size: 13px; 6 | line-height: 18px; 7 | } 8 | 9 | p, ol, ul, td { 10 | font-family: verdana, arial, helvetica, sans-serif; 11 | font-size: 13px; 12 | line-height: 18px; 13 | } 14 | 15 | pre { 16 | background-color: #eee; 17 | padding: 10px; 18 | font-size: 11px; 19 | } 20 | 21 | a { 22 | color: #000; 23 | &:visited { 24 | color: #666; 25 | } 26 | &:hover { 27 | color: #fff; 28 | background-color: #000; 29 | } 30 | } 31 | 32 | div { 33 | &.field, &.actions { 34 | margin-bottom: 10px; 35 | } 36 | } 37 | 38 | #notice { 39 | color: green; 40 | } 41 | 42 | .field_with_errors { 43 | padding: 2px; 44 | background-color: red; 45 | display: table; 46 | } 47 | 48 | #error_explanation { 49 | width: 450px; 50 | border: 2px solid red; 51 | padding: 7px; 52 | padding-bottom: 0; 53 | margin-bottom: 20px; 54 | background-color: #f0f0f0; 55 | h2 { 56 | text-align: left; 57 | font-weight: bold; 58 | padding: 5px 5px 5px 15px; 59 | font-size: 12px; 60 | margin: -7px; 61 | margin-bottom: 0px; 62 | background-color: #c00; 63 | color: #fff; 64 | } 65 | ul li { 66 | font-size: 12px; 67 | list-style: square; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /apis/api_lesson/app/controllers/api/api_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::ApiController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :null_session 5 | end 6 | -------------------------------------------------------------------------------- /apis/api_lesson/app/controllers/api/v1/players_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::PlayersController < Api::ApiController 2 | 3 | def index 4 | @players = Player.all 5 | respond_to do |format| 6 | format.json { render json: @players } 7 | format.xml { render xml: @players } 8 | end 9 | end 10 | 11 | def show 12 | @player = Player.find_by(id: params[:id]) 13 | 14 | if @player.nil? 15 | respond_to do |format| 16 | format.json { render json: "Player not found", status: :not_found } 17 | format.xml { render xml: ["Player not found"], status: :not_found } 18 | end 19 | else 20 | respond_to do |format| 21 | format.json { render json: @player } 22 | format.xml { render xml: @player } 23 | end 24 | end 25 | end 26 | 27 | def create 28 | @player = Player.new(player_params) 29 | 30 | if @player.save 31 | render json: @player, status: :created 32 | else 33 | render json: @player.errors.full_messages, status: :unprocessable_entity 34 | end 35 | end 36 | 37 | 38 | private 39 | 40 | 41 | def player_params 42 | params.require(:player).permit(:name, :country, :number) 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /apis/api_lesson/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /apis/api_lesson/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /apis/api_lesson/app/controllers/players_controller.rb: -------------------------------------------------------------------------------- 1 | class PlayersController < ApplicationController 2 | before_action :set_player, only: [:show, :edit, :update, :destroy] 3 | 4 | # GET /players 5 | # GET /players.json 6 | def index 7 | @players = Player.all 8 | end 9 | 10 | # GET /players/1 11 | # GET /players/1.json 12 | def show 13 | end 14 | 15 | # GET /players/new 16 | def new 17 | @player = Player.new 18 | end 19 | 20 | # GET /players/1/edit 21 | def edit 22 | end 23 | 24 | # POST /players 25 | # POST /players.json 26 | def create 27 | @player = Player.new(player_params) 28 | 29 | respond_to do |format| 30 | if @player.save 31 | format.html { redirect_to @player, notice: 'Player was successfully created.' } 32 | format.json { render :show, status: :created, location: @player } 33 | else 34 | format.html { render :new } 35 | format.json { render json: @player.errors, status: :unprocessable_entity } 36 | end 37 | end 38 | end 39 | 40 | # PATCH/PUT /players/1 41 | # PATCH/PUT /players/1.json 42 | def update 43 | respond_to do |format| 44 | if @player.update(player_params) 45 | format.html { redirect_to @player, notice: 'Player was successfully updated.' } 46 | format.json { render :show, status: :ok, location: @player } 47 | else 48 | format.html { render :edit } 49 | format.json { render json: @player.errors, status: :unprocessable_entity } 50 | end 51 | end 52 | end 53 | 54 | # DELETE /players/1 55 | # DELETE /players/1.json 56 | def destroy 57 | @player.destroy 58 | respond_to do |format| 59 | format.html { redirect_to players_url, notice: 'Player was successfully destroyed.' } 60 | format.json { head :no_content } 61 | end 62 | end 63 | 64 | private 65 | # Use callbacks to share common setup or constraints between actions. 66 | def set_player 67 | @player = Player.find(params[:id]) 68 | end 69 | 70 | # Never trust parameters from the scary internet, only allow the white list through. 71 | def player_params 72 | params.require(:player).permit(:name, :country, :number) 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /apis/api_lesson/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /apis/api_lesson/app/helpers/players_helper.rb: -------------------------------------------------------------------------------- 1 | module PlayersHelper 2 | end 3 | -------------------------------------------------------------------------------- /apis/api_lesson/app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/app/mailers/.keep -------------------------------------------------------------------------------- /apis/api_lesson/app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/app/models/.keep -------------------------------------------------------------------------------- /apis/api_lesson/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/app/models/concerns/.keep -------------------------------------------------------------------------------- /apis/api_lesson/app/models/player.rb: -------------------------------------------------------------------------------- 1 | class Player < ActiveRecord::Base 2 | validates :name, presence: true 3 | validates :country, presence: true 4 | 5 | def as_json(options={}) 6 | super(only: [:name, :country, :number]) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ApiLesson 5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@player) do |f| %> 2 | <% if @player.errors.any? %> 3 |
4 |

<%= pluralize(@player.errors.count, "error") %> prohibited this player from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :name %>
16 | <%= f.text_field :name %> 17 |
18 |
19 | <%= f.label :country %>
20 | <%= f.text_field :country %> 21 |
22 |
23 | <%= f.label :number %>
24 | <%= f.number_field :number %> 25 |
26 |
27 | <%= f.submit %> 28 |
29 | <% end %> 30 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Player

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @player %> | 6 | <%= link_to 'Back', players_path %> 7 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

Listing Players

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% @players.each do |player| %> 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | <% end %> 26 | 27 |
NameCountryNumber
<%= player.name %><%= player.country %><%= player.number %><%= link_to 'Show', player %><%= link_to 'Edit', edit_player_path(player) %><%= link_to 'Destroy', player, method: :delete, data: { confirm: 'Are you sure?' } %>
28 | 29 |
30 | 31 | <%= link_to 'New Player', new_player_path %> 32 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@players) do |player| 2 | json.extract! player, :id, :name, :country, :number 3 | json.url player_url(player, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Player

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', players_path %> 6 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @player.name %> 6 |

7 | 8 |

9 | Country: 10 | <%= @player.country %> 11 |

12 | 13 |

14 | Number: 15 | <%= @player.number %> 16 |

17 | 18 | <%= link_to 'Edit', edit_player_path(@player) %> | 19 | <%= link_to 'Back', players_path %> 20 | -------------------------------------------------------------------------------- /apis/api_lesson/app/views/players/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @player, :name, :country, :number -------------------------------------------------------------------------------- /apis/api_lesson/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /apis/api_lesson/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /apis/api_lesson/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /apis/api_lesson/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /apis/api_lesson/bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /apis/api_lesson/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /apis/api_lesson/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | require "active_model/railtie" 6 | require "active_job/railtie" 7 | require "active_record/railtie" 8 | require "action_controller/railtie" 9 | require "action_mailer/railtie" 10 | require "action_view/railtie" 11 | require "sprockets/railtie" 12 | # require "rails/test_unit/railtie" 13 | 14 | # Require the gems listed in Gemfile, including any gems 15 | # you've limited to :test, :development, or :production. 16 | Bundler.require(*Rails.groups) 17 | 18 | module ApiLesson 19 | class Application < Rails::Application 20 | # Settings in config/environments/* take precedence over those specified here. 21 | # Application configuration should go into files in config/initializers 22 | # -- all .rb files in that directory are automatically loaded. 23 | 24 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 25 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 26 | # config.time_zone = 'Central Time (US & Canada)' 27 | 28 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 29 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 30 | # config.i18n.default_locale = :de 31 | 32 | # Do not swallow errors in after_commit/after_rollback callbacks. 33 | config.active_record.raise_in_transactional_callbacks = true 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apis/api_lesson/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /apis/api_lesson/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /apis/api_lesson/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /apis/api_lesson/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /apis/api_lesson/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | # config.assets.css_compressor = :sass 30 | 31 | # Do not fallback to assets pipeline if a precompiled asset is missed. 32 | config.assets.compile = false 33 | 34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 35 | # yet still be able to expire them through the digest params. 36 | config.assets.digest = true 37 | 38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 39 | 40 | # Specifies the header that your server uses for sending files. 41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | # config.log_tags = [ :subdomain, :uuid ] 53 | 54 | # Use a different logger for distributed setups. 55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 61 | # config.action_controller.asset_host = 'http://assets.example.com' 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Use default logging formatter so that PID and timestamp are not suppressed. 75 | config.log_formatter = ::Logger::Formatter.new 76 | 77 | # Do not dump schema after migrations. 78 | config.active_record.dump_schema_after_migration = false 79 | end 80 | -------------------------------------------------------------------------------- /apis/api_lesson/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'API' 16 | # end 17 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_api_lesson_session' 4 | -------------------------------------------------------------------------------- /apis/api_lesson/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /apis/api_lesson/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /apis/api_lesson/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root 'players#index' 3 | resources :players 4 | 5 | namespace :api, path: '', constraints: { subdomain: 'api' }, defaults: { format: 'json' } do 6 | namespace :v1 do 7 | resources :players 8 | end 9 | end 10 | # The priority is based upon order of creation: first created -> highest priority. 11 | # See how all your routes lay out with "rake routes". 12 | 13 | # You can have the root of your site routed with "root" 14 | # root 'welcome#index' 15 | 16 | # Example of regular route: 17 | # get 'products/:id' => 'catalog#view' 18 | 19 | # Example of named route that can be invoked with purchase_url(id: product.id) 20 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase 21 | 22 | # Example resource route (maps HTTP verbs to controller actions automatically): 23 | # resources :products 24 | 25 | # Example resource route with options: 26 | # resources :products do 27 | # member do 28 | # get 'short' 29 | # post 'toggle' 30 | # end 31 | # 32 | # collection do 33 | # get 'sold' 34 | # end 35 | # end 36 | 37 | # Example resource route with sub-resources: 38 | # resources :products do 39 | # resources :comments, :sales 40 | # resource :seller 41 | # end 42 | 43 | # Example resource route with more complex sub-resources: 44 | # resources :products do 45 | # resources :comments 46 | # resources :sales do 47 | # get 'recent', on: :collection 48 | # end 49 | # end 50 | 51 | # Example resource route with concerns: 52 | # concern :toggleable do 53 | # post 'toggle' 54 | # end 55 | # resources :posts, concerns: :toggleable 56 | # resources :photos, concerns: :toggleable 57 | 58 | # Example resource route within a namespace: 59 | # namespace :admin do 60 | # # Directs /admin/products/* to Admin::ProductsController 61 | # # (app/controllers/admin/products_controller.rb) 62 | # resources :products 63 | # end 64 | end 65 | -------------------------------------------------------------------------------- /apis/api_lesson/config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: e1af57754d5310a458dbc6ecbcf818e2462aa0c2f98aa76f3dce5598cefc7eb3ce40f4ccf02d8759902638943a415b520662d2f27326e9146a01de82a7c2f87c 15 | 16 | test: 17 | secret_key_base: 7d82b095992f6e98abc39fdfe5a0d769e6db1822ec9a078e3b37691db69ac2ea59c3d44807bf01130c3255b57568c4d2d5efa58881e6a6b3952790ccb10d128b 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /apis/api_lesson/db/migrate/20150708021926_create_players.rb: -------------------------------------------------------------------------------- 1 | class CreatePlayers < ActiveRecord::Migration 2 | def change 3 | create_table :players do |t| 4 | t.string :name 5 | t.string :country 6 | t.integer :number 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apis/api_lesson/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20150708021926) do 15 | 16 | create_table "players", force: :cascade do |t| 17 | t.string "name" 18 | t.string "country" 19 | t.integer "number" 20 | t.datetime "created_at", null: false 21 | t.datetime "updated_at", null: false 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /apis/api_lesson/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /apis/api_lesson/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/lib/assets/.keep -------------------------------------------------------------------------------- /apis/api_lesson/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/lib/tasks/.keep -------------------------------------------------------------------------------- /apis/api_lesson/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/log/.keep -------------------------------------------------------------------------------- /apis/api_lesson/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /apis/api_lesson/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /apis/api_lesson/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /apis/api_lesson/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/public/favicon.ico -------------------------------------------------------------------------------- /apis/api_lesson/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /apis/api_lesson/vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /apis/api_lesson/vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-school/lessons/fbb2076e82be50f3ddd0a7f9f77c57d025794b19/apis/api_lesson/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /swift-walkthrough/part1.md: -------------------------------------------------------------------------------- 1 | # Swift walkthrough 2 | 3 | ## Var declarations 4 | 5 | ```swift 6 | var aBool = true 7 | let myString: String = "foo" 8 | var aInt = 56 9 | 10 | myString = "bar" // Error 11 | ``` 12 | 13 | Basic types: Bool, Int, Double, Float, String 14 | 15 | ## Optionals 16 | 17 | ```swift 18 | var i: Int? // current value = nil 19 | var b: Bool? 20 | 21 | var s: String // Compile error 22 | 23 | // Test if value is different than nil 24 | if let aBool = b { 25 | // ... 26 | } 27 | 28 | if b! { // Runtime error if nil 29 | // ... 30 | } 31 | ``` 32 | 33 | **All non optional variables must have a value.** 34 | 35 | ## Arrays / Dictionaries / Tuples 36 | 37 | ```swift 38 | var anArray: [Int] = [1, 2, 3] 39 | var emptyArray = [Int]() 40 | 41 | var aDictionary: [String: String?] = [ 42 | "foo": nil, 43 | "bar": "barfoo" 44 | ] 45 | var emptyDictionary: [String: String?] = [:] 46 | 47 | let e = anArray[2] // e = 3 48 | let s = aDictionary["foo"] // s = nil 49 | ``` 50 | 51 | ```swift 52 | var t: (firstElement: Int, secondElement: String) = (firstElement: 3, secondElement: "foo") 53 | 54 | // t.firstElement = 3 55 | 56 | let (a, b) = t 57 | // a = 3 58 | // b = "foo" 59 | 60 | var e = (200, "ok") 61 | // e.1 = "ok" 62 | ``` 63 | 64 | ## Conditions 65 | 66 | ```swift 67 | if myBool && myArray[3] == 89 { 68 | // ... 69 | } else if myArray[0] < 67 || myArray[1] > 0 { 70 | // ... 71 | } else { 72 | // ... 73 | } 74 | ``` 75 | 76 | ```swift 77 | switch (myValue) { 78 | case 0: 79 | // Do some stuff 80 | case 1: 81 | // Another stuff 82 | // In Swift, break keyword is optional. 83 | // If you would like to run cascade cases, use fallthrough keyword 84 | default: 85 | // Default case 86 | break // No instruction, so I need a break 87 | } 88 | ``` 89 | 90 | ## Loops 91 | 92 | ```swift 93 | while myBool { 94 | // ... 95 | } 96 | 97 | do { 98 | // ... 99 | } while myCondition 100 | ``` 101 | 102 | ```swift 103 | for var i = 0; i < 100; i++ { 104 | // ... 105 | } 106 | 107 | for i in 0...99 { 108 | // ... 109 | } 110 | 111 | for i in 0..<100 { 112 | // ... 113 | } 114 | ``` 115 | 116 | ```swift 117 | for e in [1, 2, 3] { 118 | // ... 119 | } 120 | 121 | for (a, b) in ["foo": 3, "bar": 4] { 122 | // ... 123 | } 124 | 125 | for c in "Foo" { 126 | // ... 127 | } 128 | ``` 129 | 130 | ## Functions 131 | 132 | ```swift 133 | func myFunc(arg1: Int, arg2: String) -> Bool { 134 | return true 135 | } 136 | 137 | myFunc(4, arg2: "foo") // Error if not a method 138 | myFunc(4, "foo") // Error if method 139 | ``` 140 | 141 | ```swift 142 | func myFunc(externalName internalArg: String, secondExternalName secondInternalName: String) { 143 | // ... 144 | } 145 | 146 | myFunc("foo", secondExternalName: "bar") 147 | myFunc("foo", secondInternalName: "bar") // Error 148 | myFunc(externalName: "foo", secondExternalName: "bar") // Error 149 | ``` 150 | 151 | ## Exercices 152 | 153 | ### Sheep array 154 | 155 | Array of bool => Returns number of true in that array 156 | 157 | ```swift 158 | func sheepArray(a: [Bool]) -> Int { 159 | var i = 0 160 | for e in a { 161 | if e { 162 | i++ 163 | } 164 | } 165 | 166 | return i 167 | } 168 | ``` 169 | 170 | ### Array difference 171 | 172 | ```swift 173 | func diff(a: [Int], b: [Int]) -> [Int] { 174 | var outcome = [Int]() 175 | 176 | for i in a { 177 | var isInB = false 178 | for j in b { 179 | if i == j { 180 | isInB = true 181 | } 182 | } 183 | 184 | if !isInB { 185 | outcome.append(i) 186 | } 187 | } 188 | 189 | return outcome 190 | } 191 | ``` 192 | 193 | ### Dictionary selection 194 | 195 | ```swift 196 | func select(d: [String: String], f: (String, String) -> Bool) -> [String: String] { 197 | var outcome: [String: String] = [:] 198 | 199 | for (key, value) in d { 200 | if f(key, value) { 201 | outcome[key] = value 202 | } 203 | } 204 | 205 | return outcome 206 | } 207 | ``` 208 | 209 | ### Turkish social security number 210 | 211 | Every Turkish citizen has an identity number whose validity can be checked by these set of rules: 212 | 213 | * It is an 11 digit number 214 | * First digit can't be zero 215 | * Take the sum of 1st, 3rd, 5th, 7th and 9th digit and multiply it by 7. Then subtract the sum of 2nd, 4th, 6th and 8th digits from this value. Modulus 10 of the result should be equal to 10th digit. 216 | * Sum of first ten digits' modulus 10 should be equal to eleventh digit. 217 | 218 | ```swift 219 | extension String { 220 | subscript (i: Int) -> Character { 221 | return self[advance(self.startIndex, i)] 222 | } 223 | 224 | subscript (i: Int) -> String { 225 | return String(self[i] as Character) 226 | } 227 | } 228 | 229 | func checkValidTurkishNumber(n: Int) -> Bool { 230 | if n <= 0 { 231 | println("Negative number") 232 | return false 233 | } 234 | 235 | var s = String(n) 236 | if count(s) != 11 { 237 | println("Invalid size") 238 | return false 239 | } 240 | 241 | if s[0].toInt()! == 0 { 242 | println("First number is a zero") 243 | return false 244 | } 245 | 246 | var a = (s[0].toInt()! + s[2].toInt()! + s[4].toInt()! + s[6].toInt()! + s[8].toInt()!) * 7 247 | a -= (s[1].toInt()! + s[3].toInt()! + s[5].toInt()! + s[7].toInt()!) 248 | 249 | if a % 10 != s[9].toInt()! { 250 | println("Computation does not match 10th number") 251 | return false 252 | } 253 | 254 | var b = 0 255 | for i in 0.. String { 178 | // In this scope, I can use a, b and c args 179 | 180 | // To call this function, I need to match this pattern: 181 | // myDuck.methodWithManyArgs(45, externalLabel: "bar", c: 90.87) 182 | // First argument label is omitted, other ones are required 183 | return "foo" 184 | } 185 | } 186 | ``` 187 | 188 | ### Access control 189 | 190 | * **Public**: Full access 191 | * **Internal**: Relative to module 192 | * **Private**: Relative to enclosing class 193 | 194 | ### Inheritance 195 | 196 | ```swift 197 | class Animal { 198 | var name: String 199 | 200 | init(name: String) { 201 | self.name = name 202 | } 203 | 204 | func saySomething() { 205 | println("Default sound") 206 | } 207 | } 208 | 209 | class Duck: Animal { 210 | var age: Int 211 | 212 | init(name: String, age: Int) { 213 | // First step: initialize all child's members 214 | self.age = age 215 | 216 | // Once done, I can call the parent initializer 217 | super.init(name: name) 218 | 219 | // After the call, I can change the parent's fields 220 | // if needed. I cannot use them before 221 | } 222 | 223 | // Overidding parent's method 224 | override func saySomething() { 225 | println("Qwak!") 226 | } 227 | } 228 | ``` 229 | 230 | This construction process ensures your class is not partially initialized before initializing the parent. 231 | 232 | ### Casting 233 | 234 | ```swift 235 | class A { 236 | } 237 | 238 | class B: A { 239 | } 240 | 241 | class C { 242 | } 243 | 244 | var b = B() 245 | var a1: A = b as! A // Force casting 246 | 247 | var c = C() 248 | var a2: A? = c as? A // Try casting, if failed, return nil 249 | 250 | if b is A { 251 | // Test typing 252 | } 253 | ``` 254 | 255 | ## Structures 256 | 257 | ```swift 258 | struct Point { 259 | var x: Double, y: Double 260 | 261 | init(x: Double, y: Double) { 262 | self.x = x 263 | self.y = y 264 | } 265 | } 266 | ``` 267 | 268 | Differences with classes: 269 | 270 | * Structures are passed by value every time. Classes are passed by reference. 271 | * Structures do not support inheritance. 272 | * Structures have (usually) a lighter impact on memory performances. 273 | * When initializing a structure, you can only have a single reference to it. 274 | * Classes support casting. 275 | 276 | 277 | ## Closures 278 | 279 | ```swift 280 | var closure = { (a: Int, b: String, c: Double) -> String in 281 | // ... 282 | return "foo" 283 | } 284 | 285 | // Equivalent to: 286 | var closure: ((Int, String, Double) -> String) = { a, b, c in 287 | // ... 288 | return "foo" 289 | } 290 | 291 | // Equivalent to: 292 | var closure: ((Int, String, Double) -> String) = { _, _, _ in 293 | // Use _ to ignore argument 294 | return "foo" 295 | } 296 | 297 | // Also equivalent to: 298 | closure = { 299 | // You can use positional arguments 300 | // However you need to use all of them 301 | // in situations where their type is guessable 302 | // $0 == a 303 | // $1 == b 304 | // $2 == c 305 | return "foo" 306 | } 307 | ``` 308 | 309 | ```swift 310 | func runAnimation(myObjectToAnimate: View, completion: () -> Void) { 311 | // ... 312 | } 313 | 314 | runAnimation(myObject, completion: { 315 | // Define here your completion handler 316 | }) 317 | 318 | // Equivalent to: 319 | runAnimation(myObject) { 320 | // Define here your completion handler 321 | } 322 | // When a closure is the latest argument, you can pass it as a trailing 323 | // closure 324 | ``` 325 | 326 | As it is a closure, you can capture external variables inside your function. You can perform any operation on them. 327 | 328 | **NB:** When using a closure within a class, you need to use the `self` keyword anytime you would like to use either a field or a method. 329 | 330 | ## Time to exercise 331 | 332 | 1. Create a `Person` class with those fields: `name` and `age`. 333 | 2. Create a `Player` and `Spectator` classes inheriting from `Person`. `Player` has an extra field named `gameNumber`, with a default value of 0. 334 | 3. Create a `Stadium` class with these fields: `name`, `capacity` and an optional `anthem`, which has the `Anthem` type. Add a convenience initializer setting the three properties in the same time. 335 | 4. Create a `Team` class pairing a stadium and a list of players. 336 | 5. Add a `playAgainst(anotherTeam: Team)` to the `Team` class. This method updates the `gameNumber` field from each player. 337 | 338 | ```swift 339 | class Person { 340 | var name: String 341 | var age: Int 342 | 343 | init(name: String, age: Int) { 344 | self.name = name 345 | self.age = age 346 | } 347 | } 348 | 349 | class Player: Person { 350 | var gameNumber: Int 351 | 352 | override init(name: String, age: Int) { 353 | gameNumber = 0 354 | 355 | super.init(name: name, age: age) 356 | } 357 | } 358 | 359 | class Spectator: Person { 360 | override init(name: String, age: Int) { 361 | super.init(name: name, age: age) 362 | } 363 | } 364 | 365 | class Anthem { 366 | } 367 | 368 | class Stadium { 369 | var name: String 370 | var capacity: Int 371 | var anthem: Anthem? 372 | 373 | init(name: String, capacity: Int) { 374 | self.name = name 375 | self.capacity = capacity 376 | } 377 | 378 | convenience init(name: String, capacity: Int, anthem: Anthem) { 379 | self.init(name: name, capacity: capacity) 380 | 381 | self.anthem = anthem 382 | } 383 | } 384 | 385 | class Team { 386 | var stadium: Stadium 387 | var players: [Player] 388 | 389 | init(stadium: Stadium, players: [Player]) { 390 | self.stadium = stadium 391 | self.players = players 392 | } 393 | 394 | func playAgainst(anotherTeam: Team) { 395 | for e in players { 396 | e.gameNumber++ 397 | } 398 | 399 | for e in anotherTeam.players { 400 | e.gameNumber++ 401 | } 402 | } 403 | } 404 | ``` 405 | --------------------------------------------------------------------------------