From 9812e56536c3c9e012d7ce9811adde7082b9ee80 Mon Sep 17 00:00:00 2001 From: Taisir Hassan <85134103+taisirhassan@users.noreply.github.com> Date: Mon, 29 Jan 2024 17:30:39 -0500 Subject: [PATCH 1/7] Implemented CRUD actions, including create, read, update, and delete on an article model. --- .gitignore | 2 + Gemfile | 2 +- Gemfile.lock | 2 +- app/controllers/articles_controller.rb | 49 ++++++++++++++++++++ app/helpers/articles_helper.rb | 2 + app/models/article.rb | 3 ++ app/views/articles/_form.html.erb | 21 +++++++++ app/views/articles/edit.html.erb | 3 ++ app/views/articles/index.html.erb | 11 +++++ app/views/articles/new.html.erb | 3 ++ app/views/articles/show.html.erb | 11 +++++ config/routes.rb | 3 ++ db/migrate/20240129213444_create_articles.rb | 10 ++++ db/schema.rb | 21 +++++++++ test/controllers/articles_controller_test.rb | 7 +++ 15 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 app/controllers/articles_controller.rb create mode 100644 app/helpers/articles_helper.rb create mode 100644 app/models/article.rb create mode 100644 app/views/articles/_form.html.erb create mode 100644 app/views/articles/edit.html.erb create mode 100644 app/views/articles/index.html.erb create mode 100644 app/views/articles/new.html.erb create mode 100644 app/views/articles/show.html.erb create mode 100644 db/migrate/20240129213444_create_articles.rb create mode 100644 db/schema.rb create mode 100644 test/controllers/articles_controller_test.rb diff --git a/.gitignore b/.gitignore index 5fb66c9f0..a35e445cc 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ # Ignore master key for decrypting credentials and more. /config/master.key +Gemfile +Gemfile.lock diff --git a/Gemfile b/Gemfile index 7abd44d7a..28697d2a0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -ruby "3.2.3" +ruby "3.3.0" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem "rails", "~> 7.1.2" diff --git a/Gemfile.lock b/Gemfile.lock index ac898c77c..fb9a62683 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -276,7 +276,7 @@ DEPENDENCIES webdrivers RUBY VERSION - ruby 3.2.3p157 + ruby 3.3.0p0 BUNDLED WITH 2.5.5 diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb new file mode 100644 index 000000000..993244079 --- /dev/null +++ b/app/controllers/articles_controller.rb @@ -0,0 +1,49 @@ +class ArticlesController < ApplicationController + def index + @articles = Article.all + 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 + 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 + else + render :edit, status: :unprocessable_entity + end + end + + def destroy + @article = Article.find(params[:id]) + @article.destroy + + redirect_to root_path, status: :see_other + end + + private + def article_params + params.require(:article).permit(:title, :body) + end +end diff --git a/app/helpers/articles_helper.rb b/app/helpers/articles_helper.rb new file mode 100644 index 000000000..296827759 --- /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 000000000..a2d854933 --- /dev/null +++ b/app/models/article.rb @@ -0,0 +1,3 @@ +class Article < ApplicationRecord + +end diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb new file mode 100644 index 000000000..346888c21 --- /dev/null +++ b/app/views/articles/_form.html.erb @@ -0,0 +1,21 @@ +<%= form_with model: article do |form| %> +
<%= @article.body %>
+ +<%= article.content %>
<% end %><%= @article.body %>
+<%= @article.content %>
<%= article.content %>
<% end %> diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb index e42ed1642..d3db438fb 100644 --- a/app/views/articles/show.html.erb +++ b/app/views/articles/show.html.erb @@ -1,4 +1,5 @@Author: <%= @article.author %>
<%= @article.content %>
diff --git a/db/migrate/20240130010108_add_author_to_articles.rb b/db/migrate/20240130010108_add_author_to_articles.rb new file mode 100644 index 000000000..3fdc9a764 --- /dev/null +++ b/db/migrate/20240130010108_add_author_to_articles.rb @@ -0,0 +1,5 @@ +class AddAuthorToArticles < ActiveRecord::Migration[7.1] + def change + add_column :articles, :author, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 3aa5f75fc..3d0cf68bd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_01_30_005402) do +ActiveRecord::Schema[7.1].define(version: 2024_01_30_010108) do create_table "articles", force: :cascade do |t| t.string "title" t.text "content" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "status" + t.string "author" end create_table "comments", force: :cascade do |t| From 5c2d4b215f0b3c32d86eff39d44de2039c420df2 Mon Sep 17 00:00:00 2001 From: Taisir Hassan <85134103+taisirhassan@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:20:31 -0500 Subject: [PATCH 4/7] Added Date integration in the table. --- app/controllers/articles_controller.rb | 11 ++++++++--- app/models/article.rb | 4 +--- app/views/articles/index.html.erb | 2 +- app/views/articles/show.html.erb | 1 + db/migrate/20240130012020_add_date_to_articles.rb | 5 +++++ .../20240130014508_change_date_default_in_articles.rb | 9 +++++++++ .../20240130020815_remove_timestamps_from_articles.rb | 6 ++++++ db/schema.rb | 5 ++--- 8 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20240130012020_add_date_to_articles.rb create mode 100644 db/migrate/20240130014508_change_date_default_in_articles.rb create mode 100644 db/migrate/20240130020815_remove_timestamps_from_articles.rb diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 309daba8e..4a554f3f7 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -14,8 +14,12 @@ def new def create @article = Article.new(article_params) +if @article.date.nil? + @article.date = Time.current + end + if @article.save - redirect_to articles_path + redirect_to articles_path, notice: "Article was successfully created." else render :new, status: :unprocessable_entity end @@ -29,7 +33,8 @@ def update @article = Article.find(params[:id]) if @article.update(article_params) - redirect_to @article + @article.update(date: Time.current) + redirect_to @article, notice: "Article was successfully updated." else render :edit, status: :unprocessable_entity end @@ -44,6 +49,6 @@ def destroy private def article_params - params.require(:article).permit(:title, :content, :author) + params.require(:article).permit(:title, :content, :author, :date) end end diff --git a/app/models/article.rb b/app/models/article.rb index 2dd05bb49..3513fb5cc 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -1,7 +1,5 @@ class Article < ApplicationRecord -validates :author, presence: true -validates :title, presence: true -validates :content, presence: true +validates :title, :content, presence: true def self.search(term) if term diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb index 294487fd3..2ff637d7a 100644 --- a/app/views/articles/index.html.erb +++ b/app/views/articles/index.html.erb @@ -1,4 +1,4 @@ -Author: <%= @article.author %>
+Date: <%= @article.date %>
<%= @article.content %>
diff --git a/db/migrate/20240130012020_add_date_to_articles.rb b/db/migrate/20240130012020_add_date_to_articles.rb new file mode 100644 index 000000000..e91d1e2a9 --- /dev/null +++ b/db/migrate/20240130012020_add_date_to_articles.rb @@ -0,0 +1,5 @@ +class AddDateToArticles < ActiveRecord::Migration[7.1] + def change + add_column :articles, :date, :datetime + end +end diff --git a/db/migrate/20240130014508_change_date_default_in_articles.rb b/db/migrate/20240130014508_change_date_default_in_articles.rb new file mode 100644 index 000000000..64e87dc8a --- /dev/null +++ b/db/migrate/20240130014508_change_date_default_in_articles.rb @@ -0,0 +1,9 @@ +class ChangeDateDefaultInArticles < ActiveRecord::Migration[7.1] + def up + change_column :articles, :date, :datetime, default: -> { 'CURRENT_TIMESTAMP' } + end + + def down + change_column :articles, :date, :datetime, default: nil + end +end diff --git a/db/migrate/20240130020815_remove_timestamps_from_articles.rb b/db/migrate/20240130020815_remove_timestamps_from_articles.rb new file mode 100644 index 000000000..9ad768dd4 --- /dev/null +++ b/db/migrate/20240130020815_remove_timestamps_from_articles.rb @@ -0,0 +1,6 @@ +class RemoveTimestampsFromArticles < ActiveRecord::Migration[6.0] + def change + remove_column :articles, :created_at, :datetime + remove_column :articles, :updated_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 3d0cf68bd..f593b8097 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,14 +10,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_01_30_010108) do +ActiveRecord::Schema[7.1].define(version: 2024_01_30_020815) do create_table "articles", force: :cascade do |t| t.string "title" t.text "content" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.string "status" t.string "author" + t.datetime "date", default: -> { "CURRENT_TIMESTAMP" } end create_table "comments", force: :cascade do |t| From b7ff690cd1d9719ecce8c1719e6fc41cc10111f7 Mon Sep 17 00:00:00 2001 From: Taisir Hassan <85134103+taisirhassan@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:34:18 -0500 Subject: [PATCH 5/7] Added styling using Bootstrap to the page --- Gemfile | 2 + Gemfile.lock | 19 +++++++ .../{application.css => application.scss} | 9 ++++ app/javascript/application.js | 8 ++- app/views/articles/_form.html.erb | 51 +++++++++++-------- app/views/articles/edit.html.erb | 1 - app/views/articles/index.html.erb | 45 ++++++++++------ app/views/articles/show.html.erb | 27 +++++----- config/routes.rb | 1 + 9 files changed, 110 insertions(+), 53 deletions(-) rename app/assets/stylesheets/{application.css => application.scss} (88%) diff --git a/Gemfile b/Gemfile index 28697d2a0..5e25721a4 100644 --- a/Gemfile +++ b/Gemfile @@ -66,3 +66,5 @@ group :test do gem "selenium-webdriver" gem "webdrivers" end + +gem 'bootstrap', '~> 5.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index fb9a62683..b9e794ce8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,11 +77,17 @@ GEM tzinfo (~> 2.0) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) + autoprefixer-rails (10.4.16.0) + execjs (~> 2) base64 (0.2.0) bigdecimal (3.1.6) bindex (0.8.1) bootsnap (1.17.1) msgpack (~> 1.2) + bootstrap (5.0.2) + autoprefixer-rails (>= 9.1.0) + popper_js (>= 2.9.2, < 3) + sassc-rails (>= 2.0.0) builder (3.2.4) capybara (3.39.2) addressable @@ -102,6 +108,8 @@ GEM drb (2.2.0) ruby2_keywords erubi (1.12.0) + execjs (2.9.1) + ffi (1.16.3) globalid (1.2.1) activesupport (>= 6.1) i18n (1.14.1) @@ -153,6 +161,7 @@ GEM racc (~> 1.4) nokogiri (1.16.0-x86_64-linux) racc (~> 1.4) + popper_js (2.11.8) psych (5.1.2) stringio public_suffix (5.0.4) @@ -205,6 +214,14 @@ GEM rexml (3.2.6) ruby2_keywords (0.0.5) rubyzip (2.3.2) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt selenium-webdriver (4.10.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) @@ -226,6 +243,7 @@ GEM railties (>= 6.0.0) stringio (3.1.0) thor (1.3.0) + tilt (2.3.0) timeout (0.4.1) turbo-rails (1.5.0) actionpack (>= 6.0.0) @@ -260,6 +278,7 @@ PLATFORMS DEPENDENCIES bootsnap + bootstrap (~> 5.0.1) capybara debug importmap-rails diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.scss similarity index 88% rename from app/assets/stylesheets/application.css rename to app/assets/stylesheets/application.scss index 288b9ab71..c07201e93 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.scss @@ -13,3 +13,12 @@ *= require_tree . *= require_self */ + + + //Import Bootstrap styles + @import "bootstrap"; + + + body { + background-color: #333; + } \ No newline at end of file diff --git a/app/javascript/application.js b/app/javascript/application.js index 0d7b49404..ecb58706c 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,3 +1,7 @@ +//= require bootstrap + +// Added bootstrap to style + // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails -import "@hotwired/turbo-rails" -import "controllers" +import "@hotwired/turbo-rails"; +import "controllers"; diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb index 66b11b3fe..5ae8450f9 100644 --- a/app/views/articles/_form.html.erb +++ b/app/views/articles/_form.html.erb @@ -1,24 +1,33 @@ -<%= form_with model: article do |form| %> -<%= article.content %>
+<%= article.content %>
+ <%= link_to 'Read', article, class: 'btn btn-primary' %> +Author: <%= @article.author %>
-Date: <%= @article.date %>
- -<%= @article.content %>
- -Publishing Date: <%= @article.date %>
+<%= @article.content %>
+ <%= link_to 'Edit', edit_article_path(@article), class: 'btn btn-primary' %> + <%= link_to 'Delete', article_path(@article), data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-danger' %> + <%= link_to 'Back', articles_path, class: 'btn btn-secondary' %> +<%= article.content %>
+ <%# Link to the article's show page with a 'Read' button %> <%= link_to 'Read', article, class: 'btn btn-primary' %> + <%# Link to the article's edit page with an 'Edit' button %> + <%= link_to 'Edit', edit_article_path(article), class: 'btn btn-primary' %> + <%# Link to delete the article with a 'Delete' button. + This will trigger a DELETE HTTP request to /articles/:id. + A confirmation dialog will be displayed before the article is deleted. %> + <%= link_to 'Delete', article_path(article), data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-danger' %>Publishing Date: <%= @article.date %>
+ <%# Display the content of the article %><%= @article.content %>
<%= link_to 'Edit', edit_article_path(@article), class: 'btn btn-primary' %> + <%# Display a link to delete the article. This will trigger a DELETE HTTP request to /articles/:id. + A confirmation dialog will be displayed before the article is deleted. %> <%= link_to 'Delete', article_path(@article), data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-danger' %> + <%# Display a link to the articles index page %> <%= link_to 'Back', articles_path, class: 'btn btn-secondary' %>