diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb
new file mode 100644
index 0000000..587b906
--- /dev/null
+++ b/app/controllers/articles_controller.rb
@@ -0,0 +1,69 @@
+class ArticlesController < ApplicationController
+ before_action :set_article, only: %i[ show edit update destroy ]
+
+ # GET /articles or /articles.json
+ def index
+ @articles = Article.all
+ end
+
+ # GET /articles/1 or /articles/1.json
+ def show
+ end
+
+ # GET /articles/new
+ def new
+ @article = Article.new
+ end
+
+ # GET /articles/1/edit
+ def edit
+ end
+
+ # POST /articles or /articles.json
+ def create
+ @article = Article.new(article_params)
+
+ respond_to do |format|
+ if @article.save
+ format.html { redirect_to @article, notice: "Article was successfully created." }
+ format.json { render :show, status: :created, location: @article }
+ else
+ format.html { render :new, status: :unprocessable_entity }
+ format.json { render json: @article.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /articles/1 or /articles/1.json
+ def update
+ respond_to do |format|
+ if @article.update(article_params)
+ format.html { redirect_to @article, notice: "Article was successfully updated." }
+ format.json { render :show, status: :ok, location: @article }
+ else
+ format.html { render :edit, status: :unprocessable_entity }
+ format.json { render json: @article.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /articles/1 or /articles/1.json
+ def destroy
+ @article.destroy
+ respond_to do |format|
+ format.html { redirect_to articles_url, notice: "Article was successfully destroyed." }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_article
+ @article = Article.find(params[:id])
+ end
+
+ # Only allow a list of trusted parameters through.
+ def article_params
+ params.require(:article).permit(:title, :text)
+ end
+end
diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb
new file mode 100644
index 0000000..f9b859b
--- /dev/null
+++ b/app/controllers/welcome_controller.rb
@@ -0,0 +1,4 @@
+class WelcomeController < ApplicationController
+ def index
+ end
+end
diff --git a/app/helpers/articles_helper.rb b/app/helpers/articles_helper.rb
new file mode 100644
index 0000000..2968277
--- /dev/null
+++ b/app/helpers/articles_helper.rb
@@ -0,0 +1,2 @@
+module ArticlesHelper
+end
diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb
new file mode 100644
index 0000000..eeead45
--- /dev/null
+++ b/app/helpers/welcome_helper.rb
@@ -0,0 +1,2 @@
+module WelcomeHelper
+end
diff --git a/app/javascript/application.js b/app/javascript/application.js
index 0d7b494..beff742 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -1,3 +1 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
-import "@hotwired/turbo-rails"
-import "controllers"
diff --git a/app/models/article.rb b/app/models/article.rb
new file mode 100644
index 0000000..b7a72b5
--- /dev/null
+++ b/app/models/article.rb
@@ -0,0 +1,2 @@
+class Article < ApplicationRecord
+end
diff --git a/app/views/articles/_article.html.erb b/app/views/articles/_article.html.erb
new file mode 100644
index 0000000..3c37f1a
--- /dev/null
+++ b/app/views/articles/_article.html.erb
@@ -0,0 +1,15 @@
+
+
+ Title:
+ <%= article.title %>
+
+
+
+ Text:
+ <%= article.text %>
+
+
+
+ <%= link_to "Show this article", article %>
+
+
diff --git a/app/views/articles/_article.json.jbuilder b/app/views/articles/_article.json.jbuilder
new file mode 100644
index 0000000..8f4e2e8
--- /dev/null
+++ b/app/views/articles/_article.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! article, :id, :title, :text, :created_at, :updated_at
+json.url article_url(article, format: :json)
diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb
new file mode 100644
index 0000000..ea47967
--- /dev/null
+++ b/app/views/articles/_form.html.erb
@@ -0,0 +1,27 @@
+<%= form_with(model: article) do |form| %>
+ <% if article.errors.any? %>
+
+
<%= pluralize(article.errors.count, "error") %> prohibited this article from being saved:
+
+
+ <% article.errors.each do |error| %>
+ - <%= error.full_message %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= form.label :title %>
+ <%= form.text_field :title %>
+
+
+
+ <%= form.label :text %>
+ <%= form.text_area :text %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb
new file mode 100644
index 0000000..4252d7a
--- /dev/null
+++ b/app/views/articles/edit.html.erb
@@ -0,0 +1,10 @@
+Editing article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Show this article", @article %> |
+ <%= link_to "Back to articles", articles_path %>
+
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb
new file mode 100644
index 0000000..f109472
--- /dev/null
+++ b/app/views/articles/index.html.erb
@@ -0,0 +1,9 @@
+<%= notice %>
+
+Article
+
+
+ <%= render @articles %>
+
+
+<%= link_to "New article", new_article_path %>
diff --git a/app/views/articles/index.json.jbuilder b/app/views/articles/index.json.jbuilder
new file mode 100644
index 0000000..09a21f3
--- /dev/null
+++ b/app/views/articles/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @articles, partial: "articles/article", as: :article
diff --git a/app/views/articles/new.html.erb b/app/views/articles/new.html.erb
new file mode 100644
index 0000000..ff360e1
--- /dev/null
+++ b/app/views/articles/new.html.erb
@@ -0,0 +1,9 @@
+New article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Back to articles", articles_path %>
+
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb
new file mode 100644
index 0000000..75923cb
--- /dev/null
+++ b/app/views/articles/show.html.erb
@@ -0,0 +1,10 @@
+<%= notice %>
+
+<%= render @article %>
+
+
+ <%= link_to "Edit this article", edit_article_path(@article) %> |
+ <%= link_to "Back to articles", articles_path %>
+
+ <%= button_to "Destroy this article", article_path(@article), method: :delete %>
+
diff --git a/app/views/articles/show.json.jbuilder b/app/views/articles/show.json.jbuilder
new file mode 100644
index 0000000..dd1fbb4
--- /dev/null
+++ b/app/views/articles/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "articles/article", article: @article
diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb
new file mode 100644
index 0000000..30e0a75
--- /dev/null
+++ b/app/views/welcome/index.html.erb
@@ -0,0 +1,3 @@
+Welcome
+
+<%= link_to "Articles", articles_path %>
diff --git a/bin/importmap b/bin/importmap
index d423864..36502ab 100755
--- a/bin/importmap
+++ b/bin/importmap
@@ -1,5 +1,4 @@
#!/usr/bin/env ruby
-# frozen_string_literal: true
-require_relative '../config/application'
-require 'importmap/commands'
+require_relative "../config/application"
+require "importmap/commands"
diff --git a/config/importmap.rb b/config/importmap.rb
index ee7ddf7..f0e4a1c 100644
--- a/config/importmap.rb
+++ b/config/importmap.rb
@@ -1,12 +1,6 @@
-# frozen_string_literal: true
-
# Use direct uploads for Active Storage (remember to import "@rails/activestorage" in your application.js)
# pin "@rails/activestorage", to: "activestorage.esm.js"
# Use node modules from a JavaScript CDN by running ./bin/importmap
-pin 'application'
-pin '@hotwired/turbo-rails', to: 'turbo.js'
-pin '@hotwired/stimulus', to: 'stimulus.js'
-pin '@hotwired/stimulus-importmap-autoloader', to: 'stimulus-importmap-autoloader.js'
-pin_all_from 'app/javascript/controllers', under: 'controllers'
+pin "application"
diff --git a/config/routes.rb b/config/routes.rb
index 9d06ca2..13e9914 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
Rails.application.routes.draw do
- # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
+ get 'welcome/index'
- # Almost every application defines a route for the root path ("/") at the top of this file.
- # root "articles#index"
+ resources :articles
+
+ root 'welcome#index'
end
diff --git a/db/migrate/20210926221100_create_articles.rb b/db/migrate/20210926221100_create_articles.rb
new file mode 100644
index 0000000..b3c7ea3
--- /dev/null
+++ b/db/migrate/20210926221100_create_articles.rb
@@ -0,0 +1,10 @@
+class CreateArticles < ActiveRecord::Migration[7.0]
+ def change
+ create_table :articles do |t|
+ t.string :title
+ t.text :text
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index eb3e335..e036ec3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1,5 +1,3 @@
-# frozen_string_literal: true
-
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
@@ -12,7 +10,16 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 0) do
+ActiveRecord::Schema.define(version: 2021_09_26_221100) do
+
# These are extensions that must be enabled in order to support this database
- enable_extension 'plpgsql'
+ enable_extension "plpgsql"
+
+ create_table "articles", force: :cascade do |t|
+ t.string "title"
+ t.text "text"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ end
+
end
diff --git a/spec/helpers/articles_helper_spec.rb b/spec/helpers/articles_helper_spec.rb
new file mode 100644
index 0000000..eac039d
--- /dev/null
+++ b/spec/helpers/articles_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ArticlesHelper. For example:
+#
+# describe ArticlesHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# expect(helper.concat_strings("this","that")).to eq("this that")
+# end
+# end
+# end
+RSpec.describe ArticlesHelper, type: :helper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/helpers/welcome_helper_spec.rb b/spec/helpers/welcome_helper_spec.rb
new file mode 100644
index 0000000..a899852
--- /dev/null
+++ b/spec/helpers/welcome_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+# Specs in this file have access to a helper object that includes
+# the WelcomeHelper. For example:
+#
+# describe WelcomeHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# expect(helper.concat_strings("this","that")).to eq("this that")
+# end
+# end
+# end
+RSpec.describe WelcomeHelper, type: :helper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb
new file mode 100644
index 0000000..632e856
--- /dev/null
+++ b/spec/models/article_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Article, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/requests/articles_spec.rb b/spec/requests/articles_spec.rb
new file mode 100644
index 0000000..70398b7
--- /dev/null
+++ b/spec/requests/articles_spec.rb
@@ -0,0 +1,130 @@
+ require 'rails_helper'
+
+# This spec was generated by rspec-rails when you ran the scaffold generator.
+# It demonstrates how one might use RSpec to test the controller code that
+# was generated by Rails when you ran the scaffold generator.
+#
+# It assumes that the implementation code is generated by the rails scaffold
+# generator. If you are using any extension libraries to generate different
+# controller code, this generated spec may or may not pass.
+#
+# It only uses APIs available in rails and/or rspec-rails. There are a number
+# of tools you can use to make these specs even more expressive, but we're
+# sticking to rails and rspec-rails APIs to keep things simple and stable.
+
+RSpec.describe "/articles", type: :request do
+
+ # Article. As you add validations to Article, be sure to
+ # adjust the attributes here as well.
+ let(:valid_attributes) {
+ skip("Add a hash of attributes valid for your model")
+ }
+
+ let(:invalid_attributes) {
+ skip("Add a hash of attributes invalid for your model")
+ }
+
+ describe "GET /index" do
+ it "renders a successful response" do
+ Article.create! valid_attributes
+ get articles_url
+ expect(response).to be_successful
+ end
+ end
+
+ describe "GET /show" do
+ it "renders a successful response" do
+ article = Article.create! valid_attributes
+ get article_url(article)
+ expect(response).to be_successful
+ end
+ end
+
+ describe "GET /new" do
+ it "renders a successful response" do
+ get new_article_url
+ expect(response).to be_successful
+ end
+ end
+
+ describe "GET /edit" do
+ it "render a successful response" do
+ article = Article.create! valid_attributes
+ get edit_article_url(article)
+ expect(response).to be_successful
+ end
+ end
+
+ describe "POST /create" do
+ context "with valid parameters" do
+ it "creates a new Article" do
+ expect {
+ post articles_url, params: { article: valid_attributes }
+ }.to change(Article, :count).by(1)
+ end
+
+ it "redirects to the created article" do
+ post articles_url, params: { article: valid_attributes }
+ expect(response).to redirect_to(article_url(Article.last))
+ end
+ end
+
+ context "with invalid parameters" do
+ it "does not create a new Article" do
+ expect {
+ post articles_url, params: { article: invalid_attributes }
+ }.to change(Article, :count).by(0)
+ end
+
+ it "renders a successful response (i.e. to display the 'new' template)" do
+ post articles_url, params: { article: invalid_attributes }
+ expect(response).to be_successful
+ end
+ end
+ end
+
+ describe "PATCH /update" do
+ context "with valid parameters" do
+ let(:new_attributes) {
+ skip("Add a hash of attributes valid for your model")
+ }
+
+ it "updates the requested article" do
+ article = Article.create! valid_attributes
+ patch article_url(article), params: { article: new_attributes }
+ article.reload
+ skip("Add assertions for updated state")
+ end
+
+ it "redirects to the article" do
+ article = Article.create! valid_attributes
+ patch article_url(article), params: { article: new_attributes }
+ article.reload
+ expect(response).to redirect_to(article_url(article))
+ end
+ end
+
+ context "with invalid parameters" do
+ it "renders a successful response (i.e. to display the 'edit' template)" do
+ article = Article.create! valid_attributes
+ patch article_url(article), params: { article: invalid_attributes }
+ expect(response).to be_successful
+ end
+ end
+ end
+
+ describe "DELETE /destroy" do
+ it "destroys the requested article" do
+ article = Article.create! valid_attributes
+ expect {
+ delete article_url(article)
+ }.to change(Article, :count).by(-1)
+ end
+
+ it "redirects to the articles list" do
+ article = Article.create! valid_attributes
+ delete article_url(article)
+ expect(response).to redirect_to(articles_url)
+ end
+ end
+end
diff --git a/spec/requests/welcome_spec.rb b/spec/requests/welcome_spec.rb
new file mode 100644
index 0000000..36343d0
--- /dev/null
+++ b/spec/requests/welcome_spec.rb
@@ -0,0 +1,7 @@
+require 'rails_helper'
+
+RSpec.describe "Welcomes", type: :request do
+ describe "GET /index" do
+ pending "add some examples (or delete) #{__FILE__}"
+ end
+end
diff --git a/spec/routing/articles_routing_spec.rb b/spec/routing/articles_routing_spec.rb
new file mode 100644
index 0000000..a258c95
--- /dev/null
+++ b/spec/routing/articles_routing_spec.rb
@@ -0,0 +1,38 @@
+require "rails_helper"
+
+RSpec.describe ArticlesController, type: :routing do
+ describe "routing" do
+ it "routes to #index" do
+ expect(get: "/articles").to route_to("articles#index")
+ end
+
+ it "routes to #new" do
+ expect(get: "/articles/new").to route_to("articles#new")
+ end
+
+ it "routes to #show" do
+ expect(get: "/articles/1").to route_to("articles#show", id: "1")
+ end
+
+ it "routes to #edit" do
+ expect(get: "/articles/1/edit").to route_to("articles#edit", id: "1")
+ end
+
+
+ it "routes to #create" do
+ expect(post: "/articles").to route_to("articles#create")
+ end
+
+ it "routes to #update via PUT" do
+ expect(put: "/articles/1").to route_to("articles#update", id: "1")
+ end
+
+ it "routes to #update via PATCH" do
+ expect(patch: "/articles/1").to route_to("articles#update", id: "1")
+ end
+
+ it "routes to #destroy" do
+ expect(delete: "/articles/1").to route_to("articles#destroy", id: "1")
+ end
+ end
+end
diff --git a/spec/views/articles/edit.html.erb_spec.rb b/spec/views/articles/edit.html.erb_spec.rb
new file mode 100644
index 0000000..57d1cac
--- /dev/null
+++ b/spec/views/articles/edit.html.erb_spec.rb
@@ -0,0 +1,21 @@
+require 'rails_helper'
+
+RSpec.describe "articles/edit", type: :view do
+ before(:each) do
+ @article = assign(:article, Article.create!(
+ title: "MyString",
+ text: "MyText"
+ ))
+ end
+
+ it "renders the edit article form" do
+ render
+
+ assert_select "form[action=?][method=?]", article_path(@article), "post" do
+
+ assert_select "input[name=?]", "article[title]"
+
+ assert_select "textarea[name=?]", "article[text]"
+ end
+ end
+end
diff --git a/spec/views/articles/index.html.erb_spec.rb b/spec/views/articles/index.html.erb_spec.rb
new file mode 100644
index 0000000..a0acc23
--- /dev/null
+++ b/spec/views/articles/index.html.erb_spec.rb
@@ -0,0 +1,22 @@
+require 'rails_helper'
+
+RSpec.describe "articles/index", type: :view do
+ before(:each) do
+ assign(:articles, [
+ Article.create!(
+ title: "Title",
+ text: "MyText"
+ ),
+ Article.create!(
+ title: "Title",
+ text: "MyText"
+ )
+ ])
+ end
+
+ it "renders a list of articles" do
+ render
+ assert_select "tr>td", text: "Title".to_s, count: 2
+ assert_select "tr>td", text: "MyText".to_s, count: 2
+ end
+end
diff --git a/spec/views/articles/new.html.erb_spec.rb b/spec/views/articles/new.html.erb_spec.rb
new file mode 100644
index 0000000..50a809c
--- /dev/null
+++ b/spec/views/articles/new.html.erb_spec.rb
@@ -0,0 +1,21 @@
+require 'rails_helper'
+
+RSpec.describe "articles/new", type: :view do
+ before(:each) do
+ assign(:article, Article.new(
+ title: "MyString",
+ text: "MyText"
+ ))
+ end
+
+ it "renders new article form" do
+ render
+
+ assert_select "form[action=?][method=?]", articles_path, "post" do
+
+ assert_select "input[name=?]", "article[title]"
+
+ assert_select "textarea[name=?]", "article[text]"
+ end
+ end
+end
diff --git a/spec/views/articles/show.html.erb_spec.rb b/spec/views/articles/show.html.erb_spec.rb
new file mode 100644
index 0000000..090619c
--- /dev/null
+++ b/spec/views/articles/show.html.erb_spec.rb
@@ -0,0 +1,16 @@
+require 'rails_helper'
+
+RSpec.describe "articles/show", type: :view do
+ before(:each) do
+ @article = assign(:article, Article.create!(
+ title: "Title",
+ text: "MyText"
+ ))
+ end
+
+ it "renders attributes in " do
+ render
+ expect(rendered).to match(/Title/)
+ expect(rendered).to match(/MyText/)
+ end
+end