diff --git a/Gemfile.lock b/Gemfile.lock
index 2b317df1..0e57e675 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -147,6 +147,8 @@ GEM
racc (~> 1.4)
nokogiri (1.15.5-aarch64-linux)
racc (~> 1.4)
+ nokogiri (1.15.5-x64-mingw32)
+ racc (~> 1.4)
nokogiri (1.15.5-x86_64-linux)
racc (~> 1.4)
psych (5.1.1.1)
@@ -215,6 +217,7 @@ GEM
sqlite3 (1.6.9)
mini_portile2 (~> 2.8.0)
sqlite3 (1.6.9-aarch64-linux)
+ sqlite3 (1.6.9-x64-mingw32)
sqlite3 (1.6.9-x86_64-linux)
stimulus-rails (1.3.0)
railties (>= 6.0.0)
@@ -227,6 +230,8 @@ GEM
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
+ tzinfo-data (1.2023.4)
+ tzinfo (>= 1.0.0)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
@@ -248,6 +253,7 @@ GEM
PLATFORMS
aarch64-linux
ruby
+ x64-mingw32
x86_64-linux
DEPENDENCIES
diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb
new file mode 100644
index 00000000..84775162
--- /dev/null
+++ b/app/controllers/articles_controller.rb
@@ -0,0 +1,52 @@
+class ArticlesController < ApplicationController
+ def index
+ @articles = Article.all
+
+ if params[:query]
+ @articles = Article.search params[:query]
+ @query = params[:query]
+ end
+ end
+
+ def show
+ @article = Article.find(params[:id])
+ end
+
+ def new
+ @article = Article.new
+ end
+
+ def create
+ @article = Article.new(article_params)
+
+ if @article.save
+ redirect_to @article, notice: "Successfully created new article!"
+ else
+ render :new, status: :unprocessable_entity
+ end
+ end
+
+ def edit
+ @article = Article.find(params[:id])
+ end
+
+ def update
+ @article = Article.find(params[:id])
+ if @article.update(article_params)
+ redirect_to @article, notice: "Successfully updated article!"
+ else
+ render :edit, status: :unprocessable_entity
+ end
+ end
+
+ def destroy
+ @article = Article.find(params[:id])
+ @article.destroy
+ redirect_to root_path, notice: "Successfully deleted article!"
+ end
+
+ private
+ def article_params
+ params.require(:article).permit(:title, :content, :author, :date)
+ end
+end
diff --git a/app/helpers/articles_helper.rb b/app/helpers/articles_helper.rb
new file mode 100644
index 00000000..29682775
--- /dev/null
+++ b/app/helpers/articles_helper.rb
@@ -0,0 +1,2 @@
+module ArticlesHelper
+end
diff --git a/app/models/article.rb b/app/models/article.rb
new file mode 100644
index 00000000..e59c9f5f
--- /dev/null
+++ b/app/models/article.rb
@@ -0,0 +1,12 @@
+class Article < ApplicationRecord
+ def self.search(query)
+ # search by checking both title and content of articles
+ return Article.where("title LIKE ? OR content LIKE ?", "%#{query}%", "%#{query}%")
+ end
+
+ # title must be present and has a maximum length
+ validates :title, presence: true, length: {minimum: 1, maximum: 200}
+ # content must be present
+ validates :content, presence: true, length: { minimum: 10 }
+
+end
diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb
new file mode 100644
index 00000000..a3b01cab
--- /dev/null
+++ b/app/views/articles/_form.html.erb
@@ -0,0 +1,37 @@
+<%= form_with model: @article do |form| %>
+
+ <%= form.label :title, "Article Title" %>
+ <%= form.text_field :title %>
+ <% @article.errors.full_messages_for(:title).each do |message| %>
+
<%= message %>
+ <% end %>
+
+
+
+ <%= form.label :content, "Article Content" %>
+ <%= form.text_area :content %>
+ <% @article.errors.full_messages_for(:content).each do |message| %>
+
<%= message %>
+ <% end %>
+
+
+
+ <%= form.label :author "Author" %>
+ <%= form.text_area :author %>
+ <% @article.errors.full_messages_for(:author).each do |message| %>
+
<%= message %>
+ <% end %>
+
+
+
+ <%= form.label :date "Date Authored"%>
+ <%= form.date_select :date, include_blank: true, start_year:1990, end_year: 2024 %>
+ <% @article.errors.full_messages_for(:date).each do |message| %>
+
<%= message %>
+ <% end %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb
new file mode 100644
index 00000000..9fbbf606
--- /dev/null
+++ b/app/views/articles/edit.html.erb
@@ -0,0 +1,2 @@
+Edit Article
+<%= render 'form', article: @article %>
\ No newline at end of file
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb
new file mode 100644
index 00000000..c8a08303
--- /dev/null
+++ b/app/views/articles/index.html.erb
@@ -0,0 +1,15 @@
+<%= flash[:notice] %>
+Encyclopedia
+<%= form_tag "/articles", method: "GET" do %>
+ <%= label_tag "Filter articles" %>
+ <%= text_field_tag :query, params[:query] %>
+ <%= submit_tag "Search" %>
+<% end %>
+List of articles:
+
+ <% @articles.each do |article| %>
+ -
+ <%= link_to article.title, article %>
+
+ <% end %>
+
diff --git a/app/views/articles/new.html.erb b/app/views/articles/new.html.erb
new file mode 100644
index 00000000..94be9daf
--- /dev/null
+++ b/app/views/articles/new.html.erb
@@ -0,0 +1,2 @@
+New Article
+<%= render 'form', article: @article %>
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb
new file mode 100644
index 00000000..6f3ac6de
--- /dev/null
+++ b/app/views/articles/show.html.erb
@@ -0,0 +1,14 @@
+<%= flash[:notice] %>
+<%= @article.title %>
+<%= @article.author %>
+<%= @article.date %>
+<%= @article.content %>
+
+
+ - <%= link_to "Edit this article", edit_article_path(@article) %>
+ - <%= link_to "Delete this article", article_path(@article), data: {
+ turbo_method: :delete,
+ turbo_confirm: "Are you sure? Once deleted, this article cannot be recovered."
+ } %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
index a125ef08..1fee8637 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,7 +4,7 @@
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live.
get "up" => "rails/health#show", as: :rails_health_check
-
- # Defines the root path route ("/")
- # root "posts#index"
+
+ root "articles#index"
+ resources :articles
end
diff --git a/db/migrate/20240130012421_create_articles.rb b/db/migrate/20240130012421_create_articles.rb
new file mode 100644
index 00000000..1803ae05
--- /dev/null
+++ b/db/migrate/20240130012421_create_articles.rb
@@ -0,0 +1,10 @@
+class CreateArticles < ActiveRecord::Migration[7.1]
+ def change
+ create_table :articles do |t|
+ t.string :title
+ t.text :content
+ t.string :author
+ t.datetime :date
+ end
+ end
+end
\ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 00000000..ca0e3e3e
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,21 @@
+# 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.
+#
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema[7.1].define(version: 2024_01_30_012421) do
+ create_table "articles", force: :cascade do |t|
+ t.string "title"
+ t.text "content"
+ t.string "author"
+ t.datetime "date"
+ end
+
+end
diff --git a/test/controllers/articles_controller_test.rb b/test/controllers/articles_controller_test.rb
new file mode 100644
index 00000000..001fd786
--- /dev/null
+++ b/test/controllers/articles_controller_test.rb
@@ -0,0 +1,5 @@
+require "test_helper"
+
+class ArticlesControllerTest < ActionDispatch::IntegrationTest
+
+end