Skip to content

Commit 6d28943

Browse files
committed
Chapter 1: add Quote CRUD with system tests and Docker Selenium setup
1 parent 0e46e8e commit 6d28943

25 files changed

Lines changed: 300 additions & 20 deletions

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ gem "bootsnap", require: false
5151
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
5252
# gem "image_processing", "~> 1.2"
5353

54+
gem "simple_form", "~> 5.1.0"
55+
5456
group :development, :test do
5557
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
5658
gem "debug", platforms: %i[ mri mingw x64_mingw ]
@@ -71,5 +73,4 @@ group :test do
7173
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
7274
gem "capybara"
7375
gem "selenium-webdriver"
74-
gem "webdrivers"
7576
end

Gemfile.lock

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ GEM
205205
rexml (~> 3.2, >= 3.2.5)
206206
rubyzip (>= 1.2.2, < 3.0)
207207
websocket (~> 1.0)
208+
simple_form (5.1.0)
209+
actionpack (>= 5.2)
210+
activemodel (>= 5.2)
208211
sprockets (4.2.2)
209212
concurrent-ruby (~> 1.0)
210213
logger
@@ -229,10 +232,6 @@ GEM
229232
activemodel (>= 6.0.0)
230233
bindex (>= 0.4.0)
231234
railties (>= 6.0.0)
232-
webdrivers (5.3.1)
233-
nokogiri (~> 1.6)
234-
rubyzip (>= 1.3.0)
235-
selenium-webdriver (~> 4.0, < 4.11)
236235
websocket (1.2.11)
237236
websocket-driver (0.8.0)
238237
base64
@@ -256,12 +255,12 @@ DEPENDENCIES
256255
puma (~> 5.0)
257256
rails (~> 7.0.0)
258257
selenium-webdriver
258+
simple_form (~> 5.1.0)
259259
sprockets-rails
260260
stimulus-rails
261261
turbo-rails
262262
tzinfo-data
263263
web-console
264-
webdrivers
265264

266265
RUBY VERSION
267266
ruby 3.0.6p216
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
class QuotesController < ApplicationController
2+
before_action :set_quote, only: [:show, :edit, :update, :destroy]
3+
4+
def index
5+
@quotes = Quote.all
6+
end
7+
8+
def show
9+
end
10+
11+
def new
12+
@quote = Quote.new
13+
end
14+
15+
def create
16+
@quote = Quote.new(quote_params)
17+
18+
if @quote.save
19+
redirect_to quotes_path, notice: "Quote was successfully created."
20+
else
21+
render :new, status: :unprocessable_entity
22+
end
23+
end
24+
25+
def edit
26+
end
27+
28+
def update
29+
if @quote.update(quote_params)
30+
redirect_to quotes_path, notice: "Quote was successfully updated."
31+
else
32+
render :edit, status: :unprocessable_entity
33+
end
34+
end
35+
36+
def destroy
37+
@quote.destroy
38+
redirect_to quotes_path, notice: "Quote was successfully destroyed."
39+
end
40+
41+
private
42+
43+
def set_quote
44+
@quote = Quote.find(params[:id])
45+
end
46+
47+
def quote_params
48+
params.require(:quote).permit(:name)
49+
end
50+
end

app/helpers/quotes_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module QuotesHelper
2+
end

app/models/quote.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Quote < ApplicationRecord
2+
validates :name, presence: true
3+
4+
end

app/views/quotes/_form.html.erb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<%= simple_form_for quote, html: { class: "quote form" } do |f| %>
2+
<% if quote.errors.any? %>
3+
<div class="error-message">
4+
<%= quote.errors.full_messages.to_sentence.capitalize %>
5+
</div>
6+
<% end %>
7+
8+
<%= f.input :name, input_html: { autofocus: true } %>
9+
<%= f.submit class: "btn btn--secondary" %>
10+
<% end %>

app/views/quotes/_quote.html.erb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="quote">
2+
<%= link_to quote.name, quote_path(quote) %>
3+
<div class="quote__actions">
4+
<%= button_to "Delete",
5+
quote_path(quote),
6+
method: :delete,
7+
class: "btn btn--light" %>
8+
<%= link_to "Edit",
9+
edit_quote_path(quote),
10+
class: "btn btn--light" %>
11+
</div>
12+
</div>

app/views/quotes/edit.html.erb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<main class="container">
2+
<%= link_to sanitize("&larr; Back to quote"), quote_path(@quote) %>
3+
4+
<div class="header">
5+
<h1>Edit quote</h1>
6+
</div>
7+
8+
<%= render "form", quote: @quote %>
9+
</main>

app/views/quotes/index.html.erb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<main class="container">
2+
<div class="header">
3+
<h1>Quotes</h1>
4+
<%= link_to "New quote",
5+
new_quote_path,
6+
class: "btn btn--primary" %>
7+
</div>
8+
9+
<%= render @quotes %>
10+
</main>

app/views/quotes/new.html.erb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<main class="container">
2+
<%= link_to sanitize("&larr; Back to quotes"), quotes_path %>
3+
4+
<div class="header">
5+
<h1>New quote</h1>
6+
</div>
7+
8+
<%= render "form", quote: @quote %>
9+
</main>

0 commit comments

Comments
 (0)