From b37281c47a378c8575422cda97ae180268beb5c4 Mon Sep 17 00:00:00 2001 From: Zach Walker Date: Tue, 22 Oct 2024 08:55:49 -0700 Subject: [PATCH] Adding rails intro and modifired project 3 --- project3.md | 50 +++- schedule.md | 3 +- slides/2024f/rails_introduction/index.html | 307 +++++++++++++++++++++ 3 files changed, 346 insertions(+), 14 deletions(-) create mode 100644 slides/2024f/rails_introduction/index.html diff --git a/project3.md b/project3.md index 43c34fa..714362c 100644 --- a/project3.md +++ b/project3.md @@ -37,27 +37,51 @@ one post can have many comments. Each comment belongs to the user and the post. ## List of supported endpoints -- Navigating to the `/users` endpoint will list all `users` in your app - -- Navigating to the `/users/:id` will show the page with the information - about the `user` with the given `id` +- Navigating to `/login` will provide you with a simple form where you can enter + your username. No password is required. When you submit the login form a new + user should be created if no user matches the username or an exiting user should + be logged in if the username exists. Either way, you should be re-directed to + the root of the application `/`. This should initialized a user session and + store the identity of the user in the session. + +- Navigating to `/logout` should remove the user information from the session + +- Navigating to any page other than `/login` without a user session should result + in a re-direct to `/login` + +- Navigating to the root of the application `/` when you are logged in will show + a list of all the posts from all users in chrolological order with the most + recently created post at the top. Each post should include: + - The content of the post + - The username of the user who created the post + - The number of comments on a post (linkable to `/posts/:id` described below) + - The time the post was last updated + If the user is not logged in, they should be re-directed to the `/login` + - (Not Required) - Consider adding a search filter form input that allows you to + filter the list of posts to just those for the specified username + +- Navigating to the `/posts/:id` will show the page with the information + about the `post` with the given `id` including + - The content of the post + - The author of the post + - The list of comments for the post + - A form to add a new comment to a post. Submitting this form should + show keep the browser on the same page but show the newly posted comment - Returns 404 if the id was not found. -- From the browser, you can create the user +- From the browser, you can create a post -- From the browser, you can update the user +- From the browser, you can update a post but only if you are the author -- From the browser, you can delete the user +- From the browser, you can delete a post but only if you are the author -- There is a validation error for incorrect create or update action +- From the browser, you can comment on any post - - E.g. Each user has to have an email and an error is displayed if this - required value is not provided +- There should be a validation error for posts or comments that are attempting to influence the election. + Have fun with this. A simple example might be a validation error for posts that include + the words "Trump" or "Harris" -- Users index page (`/users`) shows the list of all the users; for each user - it shows the list of all posts that belong to the given user and for each - post it shows all the comments that belong to the post. ## Resources diff --git a/schedule.md b/schedule.md index 0c7dd4e..0653b90 100644 --- a/schedule.md +++ b/schedule.md @@ -93,7 +93,7 @@ The following schedule is subject to change, and many slide links are not yet ac ### Topics -- Client-side Caching & Content Delivery Networks +- Rails Intro [slides](/slides/2024f/rails_introduction/index.html) - Server-Side Caching ### Tasks @@ -108,6 +108,7 @@ The following schedule is subject to change, and many slide links are not yet ac ### Topics +- Guest Lecture on React (Tu 10/29) - Relational Databases - Relational Databases and Rails - RDBMS Scaling diff --git a/slides/2024f/rails_introduction/index.html b/slides/2024f/rails_introduction/index.html new file mode 100644 index 0000000..344bdee --- /dev/null +++ b/slides/2024f/rails_introduction/index.html @@ -0,0 +1,307 @@ +--- +layout: presentation +title: Introduction to Ruby on Rails +--- + +class: center, middle + +# {{page.title}} + +## CS291A: Scalable Internet Services + +--- + +## History of Ruby on Rails + +- Created in 2004 by David Heinemeier Hansson (DHH) +- Extracted from Basecamp project management tool +- Released as open-source +- Major release dates: + - 2004: Initial release (0.5) + - 2005: Rails 1.0 + - 2007: Rails 2.0 + - 2010: Rails 3.0 + - 2013: Rails 4.0 + - 2016: Rails 5.0 + - 2020: Rails 6.0 + - 2021: Rails 7.0 + +??? + +**Speaker Notes:** +- Emphasize the origin of Rails from practical needs at Basecamp. +- Highlight how it became popular quickly due to its simplicity and productivity for web applications. +- Rails versions usually introduce major enhancements, focus on 6 and 7 being recent with performance improvements and modern JavaScript support. + +--- + +## Key Benefits of Ruby on Rails + +- **Convention over Configuration (CoC)** +- **Don’t Repeat Yourself (DRY)** +- **Built-in Scalability** +- **Full-stack solution**: Includes everything from front-end to database interaction +- **Active community**: Constant improvements and large ecosystem +- **RESTful Architecture**: Favors design of modern web apps + +??? + +**Speaker Notes:** +- CoC minimizes configuration; most things work "out of the box." +- DRY ensures you write less code by abstracting common patterns. +- Rails handles web, database, and background jobs, providing an all-in-one framework. + +--- + +## Ruby on Rails vs. Other Frameworks + +| Feature | Ruby on Rails | Django | Express.js | +|------------------------|-----------------------|---------------------|------------------| +| Language | Ruby | Python | JavaScript (Node)| +| Philosophy | CoC, DRY | Explicit is better | Minimalist | +| Full-stack | Yes | Yes | No | +| ORM | ActiveRecord | Django ORM | None (MongoDB popular)| +| Performance | High (Recent versions)| High | High | +| Ecosystem | Large | Large | Moderate | + +??? + +**Speaker Notes:** +- Discuss how Rails compares to Django in terms of philosophy—Rails focuses more on conventions, Django on explicit configuration. +- Express.js is more lightweight, used primarily in Node.js ecosystems where developers want more control over the stack. + +--- + +## Convention over Configuration + +- Rails uses **default conventions** to simplify configuration + - Default folder structures: `app/models`, `app/views`, `app/controllers` + - Convention-based file names, e.g., `UserController` automatically maps to `users` table + - Migrations manage database schema changes +- Opinionated framework: makes assumptions to reduce decision fatigue + +??? + +**Speaker Notes:** +- Explain that CoC leads to faster development, reducing the number of choices developers need to make. +- Emphasize that while opinionated, Rails allows flexibility through customization if necessary. + +--- + +## Core Concepts of a Rails Application + +### 1. Model-View-Controller (MVC) + +- **Model**: Business logic and database interaction (ActiveRecord ORM) +- **View**: User-facing templates (ERB, Haml, etc.) +- **Controller**: Manages request-response lifecycle + +--- + +### 2. Models + +- Represent database tables as Ruby classes +- Utilize **ActiveRecord** ORM to abstract SQL interactions + - Example: `User.find(1)` instead of `SELECT * FROM users WHERE id = 1` + +--- + +### 3. Views + +- Present data to users through templates +- Can include logic (not recommended) and helpers for DRY + +--- + +### 4. Controllers + +- Handle incoming requests and responses +- Route logic to appropriate actions +- E.g., `def show` method for displaying user data + +--- + +### 5. Migrations + +- Version control for database schema +- Create, update, or drop tables with simple Ruby commands + - Example: `rails generate migration AddEmailToUsers email:string` + +??? + +**Speaker Notes:** +- Break down the MVC architecture and emphasize how each piece interacts. +- Mention that the model uses ActiveRecord, and migrations manage schema changes. +- Give examples of each concept and how it ties into building a real-world application. + +--- + +## Rails Application Structure + +- **app/**: Core components (models, views, controllers) +- **db/**: Database files and migrations +- **config/**: Application configurations, routes +- **lib/**: Custom libraries and reusable code +- **public/**: Static files (images, JS, CSS) + +??? + +**Speaker Notes:** +- Walk through the folder structure of a typical Rails application. +- Focus on how conventions organize files and directories to make them predictable and easy to navigate. + +--- + +## Rails Command Line Interface (CLI) + +- **`rails new app_name`**: Create a new Rails application +- **`rails generate scaffold ModelName`**: Generate MVC components +- **`rails db:migrate`**: Run pending migrations +- **`rails server`**: Start the development server +- **`rails console`**: Interactive Ruby console for testing +- **`rails routes`**: Display application routes +- **`rails dbconsole`**: Access the database console +- **`rails test`**: Run test suite + +--- + +## Rails Validations + +- Ensure data integrity and consistency +- Built-in helpers for common validations + - Presence, uniqueness, format, length, etc. + +```ruby +class User < ApplicationRecord + validates :email, presence: true, uniqueness: true +end +``` + +??? + +**Speaker Notes:** +- Explain how validations ensure data quality and prevent invalid data from entering the database. + +--- + +## Rails Associations + +- Define relationships between models +- Common associations: + - `has_many`, `belongs_to`, `has_one`, `has_and_belongs_to_many` + +```ruby +class User < ApplicationRecord + has_many :posts +end + +class Post < ApplicationRecord + belongs_to :user +end +``` + +??? + +**Speaker Notes:** +- Discuss how associations simplify querying and managing relationships between models. + +--- + +## Rails Routing + +- Maps URLs to controller actions +- RESTful routes: `GET`, `POST`, `PUT`, `DELETE` +- Define routes in `config/routes.rb` + +```ruby +Rails.application.routes.draw do + resources :users +end +``` + + +??? + +**Speaker Notes:** +- Explain how routing connects URLs to controller actions and RESTful conventions simplify API design. + +--- + +## Rails Testing + +- **Minitest**: Default testing framework +- **RSpec**: Popular alternative for BDD +- **Fixtures**: Sample data for testing +- **Factories**: Generate test data dynamically +- **System tests**: End-to-end testing with Capybara + +--- + +## Rails Controller Test Example + +Test that the `users#index` action returns the users list: +```ruby +class UsersControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get users_url + assert_response :success + assert_select "h1", "Users" + assert_select "li", User.count + assert_select "li", User.first.name + end +end +``` + +or if it is a API endoint: +```ruby +class UsersControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get users_url, as: :json + assert_response :success + assert_equal User.count, JSON.parse(response.body).size + assert_equal User.first.name, JSON.parse(response.body).first["name"] + end +end +``` +--- + +## Cookies and Sessions + +- **Cookies**: Store small pieces of data on the client side +- **Sessions**: Store user data on the server side +- Rails provides helpers for managing cookies and sessions + +```ruby +# Set a cookie +cookies[:user_id] = current_user.id + +# Access session data +session[:user_id] +``` + +--- + +## Before Action Callbacks + +- Run code before controller actions +- Common uses: + - Authenticate users + - Set instance variables + - Redirect if conditions are not met + +```ruby +class PostsController < ApplicationController + before_action :authenticate_user! + + def index + @posts = Post.all + end + + private + + def authenticate_user! + @curent_user = User.find(session[:user_id]) + redirect_to login_path unless @current_user + end +end +```