Skip to content

Instantly share code, notes, and snippets.

@usutani
Created December 26, 2021 07:26
Show Gist options
  • Save usutani/cd0336b9b2c36bf40ed7b26d3e09bb45 to your computer and use it in GitHub Desktop.
Save usutani/cd0336b9b2c36bf40ed7b26d3e09bb45 to your computer and use it in GitHub Desktop.
Rails 7: The Demo
macOS 11.6
rails 7.0.0
brew install vips
brew install redis
redis-server /usr/local/etc/redis.conf
00:00 Scaffolding
rails new demo
cd demo
rails generate scaffold post title:string content:text
mate .
rails db:migrate
cat db/schema.rb
rails server
http://localhost:3000/posts/new
Hello world!
First post!
application.html.erb
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
http://localhost:3000/posts
http://localhost:3000/posts.json
04:00 Developing the Domain Model (Post)
post.rb
validates_presence_of :title
http://localhost:3000/posts/new
Missing title!
05:08 Built in console/repl
rails console
Post.first
Post.create! title: "From the console", content: "Nice!"
Post.all
Post.where(created_at: Time.now.all_day)
Post.where(created_at: Time.now.all_day).to_sql
Post.where(created_at: Time.now.yesterday.all_day).to_sql
Post.where(created_at: Time.now.yesterday.all_day)
exit
06:15 ActionText Rails' Rich Text Editor
rails action_text:install
bundle
rails db:migrate
post.rb
has_rich_text :content
_form.html.erb
<%= form.rich_text_area :content %>
Ctrl+C
rails server
http://localhost:3000/posts/new
postx => post
This is RICH!
We can use rich text!
Rails logo
Ctrl+C
9:20 Javascript Import Maps - no node or webpack :D
application.js
importmap.rv
10:25 Adding JS packages using pins
./bin/importmap pin local-time
import LocalTime from "local-time"
LocalTime.start()
# show.html.erb demoにはlink_toが含まれている。
<p>
Posted <%= time_tag post.created_at, "data-local": "time-ago" %>
</p>
12:50 Downloading JS packages instead of using CDN
./bin/importmap pin local-time --download
13:40 Adding Comments to the Blog Post
rails g resource comment post:references content:text
cat db/migrate/*_create_comments.rb
rails db:migrate
rails console
Post.first
Post.first.comments
post.rb
has_many :comments
reload!
Post.first.comments
Post.first.comments.create! content: "First comment!"
15:40 Adding Comments to the Web UI
show.html.erb
<%= render "posts/comments", post: @post %>
_comments.html.erb
<h2>Comments</h2>
<div id="comments">
<%# Expands to render partial: "comments/comment", collection: post.comments %>
<%= render post.comments %>
</div>
<%= render "comments/new", post: post %>
_comment.html.erb
<div id="<%= dom_id(comment) %>">
<%= comment.content %>
- <%= time_tag comment.created_at, "data-local": "time-ago" %>
</div>
_new.html.erb
<%= form_with model: [ post, Comment.new ] do |form| %>
Your comment:<br>
<%= form.text_area :content, size: "20x5" %>
<%= form.submit %>
<% end %>
_post.html.erb
<p>
<strong><%= pluralize post.comments.count, "comment" %></strong>
</p>
comments_controller.rb
class CommentsController < ApplicationController
before_action :set_post
def create
@post.comments.create! params.required(:comment).permit(:content)
redirect_to @post
end
private
def set_post
@post = Post.find(params[:post_id])
end
end
routes.rb
Rails.application.routes.draw do
resources :posts do
resources :comments
end
# Defines the root path route ("/")
# root "articles#index"
end
Let's do one comment!
20:40 Adding Email Notifications with ActionMailer
exit
rails g mailer comments submitted
mate app/mailers/comments_mailer.rb
def submitted(comment)
@comment = comment
mail to: "blog-owner@example.org", subject: "New comment!"
end
submitted.html.erb
<h1>You got a new comment on <%= @comment.post.title %></h1>
<%= render @comment %>
submitted.text.erb
You got a new comment on <%= @comment.post.title %>: <%= @comment.content %>
comments_mailer_preview.rb
CommentsMailer.submitted Comment.first
http://localhost:3000/rails/mailers/comments_mailer/submitted
comments_controller.rb
comment = @post.comments.create! params.required(:comment).permit(:content)
CommentsMailer.submitted(comment).deliver_later
http://localhost:3000/posts/3
Send a comment via emai!
24:20 Live Updates via Websockets
show.html.erb
<%= turbo_stream_from @post %>
comment.rb
broadcasts_to :post
http://localhost:3000/posts/3
Ctrl+C
rails server
Is this a live comment?
rails c
Post.find(3).comments
Post.find(3).comments.last.destroy
Post.find(3).comments.last.update! content: "Updated from console!"
exit
27:30 Testing
rails test
post.rb
has_many :comments, dependent: :destroy
rails test
test/mailers/comments_mailer_test.rb
comments.yml
comments_mailer_test.rb
mail = CommentsMailer.submitted comments(:one)
assert_equal "New comment!", mail.subject
assert_equal ["blog-owner@example.org"], mail.to
assert_equal ["from@example.com"], mail.from
rails test
29:15 Deploying to Heroku
rails db:system:change --to=postgresql
y
bundle
git add .
git commit -m 'First'
heroku create
git push heroku main
bundle lock --add-platform x86_64-linux
git add Gemfile.lock
git commit -m 'Added the platform'
git push heroku main
heroku run rake db:migrate
heroku addons:create heroku-redis:hobby-dev -a __APP__
https://__APP__.herokuapp.com/
routes.rb
root "posts#index"
git add .
git commit -m 'Adding root route'
git push heroku main
This is the first post!
This is the second post.
The first comment!
The second comment!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment