From 397566d9397ee9afdfb82018e8e4fe7d0fc2d130 Mon Sep 17 00:00:00 2001 From: Emmanuel Idun <139833097+eidun10@users.noreply.github.com> Date: Thu, 18 Jan 2024 04:41:15 -0600 Subject: [PATCH 1/6] setup config to run template project (#1) Co-authored-by: Emmanuel Idun --- Gemfile.lock | 6 ++++++ 1 file changed, 6 insertions(+) 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 From ee6793b67f9d52f138d0f3ed5ea140cb5f9493aa Mon Sep 17 00:00:00 2001 From: Emmanuel Idun <139833097+eidun10@users.noreply.github.com> Date: Sun, 28 Jan 2024 00:26:33 -0600 Subject: [PATCH 2/6] New article model (#3) * model and controller for articles initialised * CRUD views for articles * init: article testing --- app/controllers/articles_controller.rb | 70 ++++++++++++++++++++ app/helpers/articles_helper.rb | 2 + app/models/article.rb | 2 + app/views/articles/_article.html.erb | 22 ++++++ app/views/articles/_article.json.jbuilder | 2 + app/views/articles/_form.html.erb | 37 +++++++++++ app/views/articles/edit.html.erb | 10 +++ app/views/articles/index.html.erb | 14 ++++ app/views/articles/index.json.jbuilder | 1 + app/views/articles/new.html.erb | 9 +++ app/views/articles/show.html.erb | 10 +++ app/views/articles/show.json.jbuilder | 1 + config/routes.rb | 2 +- db/migrate/20240125082905_create_articles.rb | 12 ++++ db/schema.rb | 23 +++++++ test/controllers/articles_controller_test.rb | 48 ++++++++++++++ test/fixtures/articles.yml | 13 ++++ test/system/articles_test.rb | 47 +++++++++++++ 18 files changed, 324 insertions(+), 1 deletion(-) 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/_article.html.erb create mode 100644 app/views/articles/_article.json.jbuilder 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/index.json.jbuilder create mode 100644 app/views/articles/new.html.erb create mode 100644 app/views/articles/show.html.erb create mode 100644 app/views/articles/show.json.jbuilder create mode 100644 db/migrate/20240125082905_create_articles.rb create mode 100644 db/schema.rb create mode 100644 test/controllers/articles_controller_test.rb create mode 100644 test/fixtures/articles.yml create mode 100644 test/system/articles_test.rb diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb new file mode 100644 index 00000000..8e1a3b1c --- /dev/null +++ b/app/controllers/articles_controller.rb @@ -0,0 +1,70 @@ +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_url(@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_url(@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, :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..b7a72b58 --- /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 00000000..faa8c66a --- /dev/null +++ b/app/views/articles/_article.html.erb @@ -0,0 +1,22 @@ +
+

+ Title: + <%= article.title %> +

+ +

+ Content: + <%= article.content %> +

+ +

+ Author: + <%= article.author %> +

+ +

+ Date: + <%= article.date %> +

+ +
diff --git a/app/views/articles/_article.json.jbuilder b/app/views/articles/_article.json.jbuilder new file mode 100644 index 00000000..2e17e23e --- /dev/null +++ b/app/views/articles/_article.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! article, :id, :title, :content, :author, :date, :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 00000000..52fe2874 --- /dev/null +++ b/app/views/articles/_form.html.erb @@ -0,0 +1,37 @@ +<%= form_with(model: article) do |form| %> + <% if article.errors.any? %> +
+

<%= pluralize(article.errors.count, "error") %> prohibited this article from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :title, style: "display: block" %> + <%= form.text_field :title %> +
+ +
+ <%= form.label :content, style: "display: block" %> + <%= form.text_area :content %> +
+ +
+ <%= form.label :author, style: "display: block" %> + <%= form.text_field :author %> +
+ +
+ <%= form.label :date, style: "display: block" %> + <%= form.date_field :date %> +
+ +
+ <%= 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..4252d7a0 --- /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 00000000..54b0d0dc --- /dev/null +++ b/app/views/articles/index.html.erb @@ -0,0 +1,14 @@ +

<%= notice %>

+ +

Articles

+ +
+ <% @articles.each do |article| %> + <%= render article %> +

+ <%= link_to "Show this article", article %> +

+ <% end %> +
+ +<%= 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 00000000..09a21f39 --- /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 00000000..ff360e12 --- /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 00000000..1c7a6475 --- /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, method: :delete %> +
diff --git a/app/views/articles/show.json.jbuilder b/app/views/articles/show.json.jbuilder new file mode 100644 index 00000000..dd1fbb4c --- /dev/null +++ b/app/views/articles/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "articles/article", article: @article diff --git a/config/routes.rb b/config/routes.rb index a125ef08..b05c485e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ Rails.application.routes.draw do # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html - + resources :articles # 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 diff --git a/db/migrate/20240125082905_create_articles.rb b/db/migrate/20240125082905_create_articles.rb new file mode 100644 index 00000000..84add4e4 --- /dev/null +++ b/db/migrate/20240125082905_create_articles.rb @@ -0,0 +1,12 @@ +class CreateArticles < ActiveRecord::Migration[7.1] + def change + create_table :articles do |t| + t.string :title + t.text :content + t.string :author + t.date :date + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000..f3918f0a --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,23 @@ +# 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_25_082905) do + create_table "articles", force: :cascade do |t| + t.string "title" + t.text "content" + t.string "author" + t.date "date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end diff --git a/test/controllers/articles_controller_test.rb b/test/controllers/articles_controller_test.rb new file mode 100644 index 00000000..c81ec881 --- /dev/null +++ b/test/controllers/articles_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class ArticlesControllerTest < ActionDispatch::IntegrationTest + setup do + @article = articles(:one) + end + + test "should get index" do + get articles_url + assert_response :success + end + + test "should get new" do + get new_article_url + assert_response :success + end + + test "should create article" do + assert_difference("Article.count") do + post articles_url, params: { article: { author: @article.author, content: @article.content, date: @article.date, title: @article.title } } + end + + assert_redirected_to article_url(Article.last) + end + + test "should show article" do + get article_url(@article) + assert_response :success + end + + test "should get edit" do + get edit_article_url(@article) + assert_response :success + end + + test "should update article" do + patch article_url(@article), params: { article: { author: @article.author, content: @article.content, date: @article.date, title: @article.title } } + assert_redirected_to article_url(@article) + end + + test "should destroy article" do + assert_difference("Article.count", -1) do + delete article_url(@article) + end + + assert_redirected_to articles_url + end +end diff --git a/test/fixtures/articles.yml b/test/fixtures/articles.yml new file mode 100644 index 00000000..67aa23dd --- /dev/null +++ b/test/fixtures/articles.yml @@ -0,0 +1,13 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyStringg + content: MyText + author: MyStringg + date: 2024-01-25 + +two: + title: MyString1 + content: MyText1 + author: MyString2 + date: 2024-01-25 diff --git a/test/system/articles_test.rb b/test/system/articles_test.rb new file mode 100644 index 00000000..3e8a6ba6 --- /dev/null +++ b/test/system/articles_test.rb @@ -0,0 +1,47 @@ +require "application_system_test_case" + +class ArticlesTest < ApplicationSystemTestCase + setup do + @article = articles(:one) + end + + test "visiting the index" do + visit articles_url + assert_selector "h1", text: "Articles" + end + + test "should create article" do + visit articles_url + click_on "New article" + + fill_in "Author", with: @article.author + fill_in "Content", with: @article.content + fill_in "Date", with: @article.date + fill_in "Title", with: @article.title + click_on "Create Article" + + assert_text "Article was successfully created" + click_on "Back" + end + + test "should update Article" do + visit article_url(@article) + click_on "Edit this article", match: :first + + fill_in "Author", with: @article.author + fill_in "Content", with: @article.content + fill_in "Date", with: @article.date + fill_in "Title", with: @article.title + click_on "Update Article" + + assert_text "Article was successfully updated" + click_on "Back" + end + + test "should destroy Article" do + visit article_url(@article) + click_on "Destroy this article", match: :first + + assert_text "Article was successfully destroyed" + end +end From 75c7f2ed737ed6083ae8b92f3ee64af2922ad920 Mon Sep 17 00:00:00 2001 From: Emmanuel Idun <139833097+eidun10@users.noreply.github.com> Date: Sun, 28 Jan 2024 22:58:33 -0600 Subject: [PATCH 3/6] Init UI for article (#4) * added home and about pages * improved ui of article pages (1) --- app/controllers/articles_controller.rb | 12 ++++++- app/controllers/pages_controller.rb | 7 +++++ app/helpers/pages_helper.rb | 2 ++ app/views/articles/_article.html.erb | 30 +++++++----------- app/views/articles/_form.html.erb | 27 +++++++--------- app/views/articles/edit.html.erb | 4 +-- app/views/articles/index.html.erb | 38 +++++++++++++++++------ app/views/articles/new.html.erb | 2 +- app/views/articles/show.html.erb | 6 ++-- app/views/layouts/_navbar.html.erb | 36 +++++++++++++++++++++ app/views/layouts/application.html.erb | 3 ++ app/views/pages/about.html.erb | 4 +++ app/views/pages/home.html.erb | 4 +++ config/routes.rb | 3 +- test/controllers/pages_controller_test.rb | 13 ++++++++ 15 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 app/controllers/pages_controller.rb create mode 100644 app/helpers/pages_helper.rb create mode 100644 app/views/layouts/_navbar.html.erb create mode 100644 app/views/pages/about.html.erb create mode 100644 app/views/pages/home.html.erb create mode 100644 test/controllers/pages_controller_test.rb diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 8e1a3b1c..cb7e35e8 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -3,7 +3,17 @@ class ArticlesController < ApplicationController # GET /articles or /articles.json def index - @articles = Article.all + @articles = Article.all + + # Sorting logic based on params[:sort] + case params[:sort] + when 'title' + @articles = @articles.order(title: :asc) + when 'author' + @articles = @articles.order(author: :asc) + when 'date' + @articles = @articles.order(date: :asc) + end end # GET /articles/1 or /articles/1.json diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb new file mode 100644 index 00000000..f5680a0c --- /dev/null +++ b/app/controllers/pages_controller.rb @@ -0,0 +1,7 @@ +class PagesController < ApplicationController + def home + end + + def about + end +end diff --git a/app/helpers/pages_helper.rb b/app/helpers/pages_helper.rb new file mode 100644 index 00000000..2c057fd0 --- /dev/null +++ b/app/helpers/pages_helper.rb @@ -0,0 +1,2 @@ +module PagesHelper +end diff --git a/app/views/articles/_article.html.erb b/app/views/articles/_article.html.erb index faa8c66a..15f31545 100644 --- a/app/views/articles/_article.html.erb +++ b/app/views/articles/_article.html.erb @@ -1,22 +1,16 @@
-

- Title: - <%= article.title %> -

-

- Content: - <%= article.content %> -

- -

- Author: - <%= article.author %> -

- -

- Date: - <%= article.date %> -

+
+
+ By <%= article.author %> +
+
+
<%= article.title %>
+

<%= article.content %>

+
+ +
diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb index 52fe2874..84146357 100644 --- a/app/views/articles/_form.html.erb +++ b/app/views/articles/_form.html.erb @@ -11,27 +11,24 @@ <% end %> -
- <%= form.label :title, style: "display: block" %> - <%= form.text_field :title %> +
+ <%= form.text_field :title, class:"form-control", placeholder:"Title" %>
-
- <%= form.label :content, style: "display: block" %> - <%= form.text_area :content %> +
+ <%= form.text_area :content, class:"form-control", placeholder:"Fill with your content" %>
-
- <%= form.label :author, style: "display: block" %> - <%= form.text_field :author %> +
+ <%= form.date_field :date, id: :article_date, class:"form-control", value:Date.today, type: :hidden %>
-
- <%= form.label :date, style: "display: block" %> - <%= form.date_field :date %> -
+ <%#
%> + <%# <%= form.text_field :user_id, id: :article_user_id, class:"form-control", value:current_user.id, type: :hidden %> + <%# %> + <%#
%> -
- <%= form.submit %> +
+ <%= form.submit "Save", class:"btn btn-primary" %>
<% end %> diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb index 4252d7a0..fd7c7391 100644 --- a/app/views/articles/edit.html.erb +++ b/app/views/articles/edit.html.erb @@ -5,6 +5,6 @@
- <%= link_to "Show this article", @article %> | - <%= link_to "Back to articles", articles_path %> + <%= link_to "Details...", @article, class:"btn btn-primary" %> + <%= link_to "Back", articles_path, class:"btn btn-dark" %>
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb index 54b0d0dc..016fe2a0 100644 --- a/app/views/articles/index.html.erb +++ b/app/views/articles/index.html.erb @@ -1,14 +1,34 @@

<%= notice %>

-

Articles

-
- <% @articles.each do |article| %> - <%= render article %> -

- <%= link_to "Show this article", article %> -

+ + + + + + + + + + + + <% if @articles.present? %> + <% @articles.each do |article| %> + + + + + + <% end %> + <% else %> + + + <% end %> - -<%= link_to "New article", new_article_path %> +
<%= link_to "Title", articles_path(sort: 'title') %><%= link_to "Author", articles_path(sort: 'author') %><%= link_to "Date", articles_path(sort: 'date') %>
<%= link_to "#{article.title}", article %><%=article.author %><%=article.date %>
No articles found.
+ +<%= link_to "New article", new_article_path, class:"btn btn-secondary" %> diff --git a/app/views/articles/new.html.erb b/app/views/articles/new.html.erb index ff360e12..f63a2ce2 100644 --- a/app/views/articles/new.html.erb +++ b/app/views/articles/new.html.erb @@ -5,5 +5,5 @@
- <%= link_to "Back to articles", articles_path %> + <%= link_to "Back", articles_path, class:"btn btn-dark" %>
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb index 1c7a6475..b95e0bfa 100644 --- a/app/views/articles/show.html.erb +++ b/app/views/articles/show.html.erb @@ -3,8 +3,8 @@ <%= render @article %>
- <%= link_to "Edit this article", edit_article_path(@article) %> | - <%= link_to "Back to articles", articles_path %> + <%= link_to "Edit", edit_article_path(@article) , class:"btn btn-secondary" %> + <%= link_to "Back", articles_path, class:"btn btn-dark" %> - <%= button_to "Destroy this article", @article, method: :delete %> + <%= button_to "Delete", @article, method: :delete, class:"btn btn-danger" %>
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb new file mode 100644 index 00000000..d088b498 --- /dev/null +++ b/app/views/layouts/_navbar.html.erb @@ -0,0 +1,36 @@ + + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 812bfb90..b3c008c1 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,9 +8,12 @@ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> + + <%= render 'layouts/navbar' %> <%= yield %> + diff --git a/app/views/pages/about.html.erb b/app/views/pages/about.html.erb new file mode 100644 index 00000000..b2cec85f --- /dev/null +++ b/app/views/pages/about.html.erb @@ -0,0 +1,4 @@ +
+

Shopify Encyclopedia

+

Shopify Encyclopedia is the place to be for all the gist within Shopify. For non-employees, you wold be able to have some transparency on our company mission and values

+
\ No newline at end of file diff --git a/app/views/pages/home.html.erb b/app/views/pages/home.html.erb new file mode 100644 index 00000000..bc850123 --- /dev/null +++ b/app/views/pages/home.html.erb @@ -0,0 +1,4 @@ +
+

Welcome to Shopify Encyclopedia

+

Feel free to browse

+
\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index b05c485e..f66e4985 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + get '/about', to: 'pages#about' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html resources :articles # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. @@ -6,5 +7,5 @@ get "up" => "rails/health#show", as: :rails_health_check # Defines the root path route ("/") - # root "posts#index" + root "pages#home" end diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb new file mode 100644 index 00000000..82565a8a --- /dev/null +++ b/test/controllers/pages_controller_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +class PagesControllerTest < ActionDispatch::IntegrationTest + test "should get home" do + get root_url + assert_response :success + end + + test "should get about" do + get about_url + assert_response :success + end +end From b2a46cae4d5a8c513acb33873c511bec926e9421 Mon Sep 17 00:00:00 2001 From: Emmanuel Idun <139833097+eidun10@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:31:03 -0600 Subject: [PATCH 4/6] Search functionality and Test fix (#5) * test error fixes * make articles table a partial * add search logic and view in navbar * articlle search html page * add input field for author name --- app/controllers/articles_controller.rb | 40 +++++++++++++++++--- app/models/article.rb | 3 ++ app/views/articles/_form.html.erb | 4 ++ app/views/articles/_table.html.erb | 24 ++++++++++++ app/views/articles/index.html.erb | 31 +-------------- app/views/articles/search.html.erb | 5 +++ app/views/articles/show.html.erb | 2 - app/views/layouts/_navbar.html.erb | 12 +----- app/views/layouts/_searchForm.html.erb | 4 ++ config/routes.rb | 1 + test/controllers/articles_controller_test.rb | 7 +++- test/fixtures/articles.yml | 13 ------- 12 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 app/views/articles/_table.html.erb create mode 100644 app/views/articles/search.html.erb create mode 100644 app/views/layouts/_searchForm.html.erb delete mode 100644 test/fixtures/articles.yml diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index cb7e35e8..04c24b99 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -3,16 +3,39 @@ class ArticlesController < ApplicationController # GET /articles or /articles.json def index - @articles = Article.all + @articles = Article.all - # Sorting logic based on params[:sort] - case params[:sort] + # Default values + sort_column = params[:sort] || 'title' + sort_order = params[:order] || 'asc' + + # Toggle the order if sorting on the same column + sort_order = toggle_order(sort_order) if sort_column == params[:sort] + + # Sorting logic based on sort_column and sort_order + case sort_column when 'title' - @articles = @articles.order(title: :asc) + @articles = @articles.order(title: sort_order) when 'author' - @articles = @articles.order(author: :asc) + @articles = @articles.order(author: sort_order) when 'date' - @articles = @articles.order(date: :asc) + @articles = @articles.order(date: sort_order) + end + end + + # GET /articles/search + def search + @query = params[:query] + @results = Article.search(@query) + + if @query.present? + if @results&.any? + @articles = @results + else + @articles = [] + end + else + @articles = Article.all end end @@ -73,6 +96,11 @@ def set_article @article = Article.find(params[:id]) end + # Tggle between ascending order and descending order + def toggle_order(order) + order == 'asc' ? 'desc' : 'asc' + end + # Only allow a list of trusted parameters through. def article_params params.require(:article).permit(:title, :content, :author, :date) diff --git a/app/models/article.rb b/app/models/article.rb index b7a72b58..263d7830 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -1,2 +1,5 @@ class Article < ApplicationRecord + def self.search(query) + where("title LIKE ? OR content LIKE ?", "%#{query}%", "%#{query}%") + end end diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb index 84146357..e41f060c 100644 --- a/app/views/articles/_form.html.erb +++ b/app/views/articles/_form.html.erb @@ -11,6 +11,10 @@
<% end %> +
+ <%= form.text_field :author, class:"form-control", placeholder:"Author" %> +
+
<%= form.text_field :title, class:"form-control", placeholder:"Title" %>
diff --git a/app/views/articles/_table.html.erb b/app/views/articles/_table.html.erb new file mode 100644 index 00000000..1d29a1d7 --- /dev/null +++ b/app/views/articles/_table.html.erb @@ -0,0 +1,24 @@ + + + + + + + + + + <% if @articles.present? %> + <% @articles.each do |article| %> + + + + + + <% end %> + <% else %> + + + + <% end %> + +
<%= link_to "Title", articles_path(sort: 'title') %><%= link_to "Author", articles_path(sort: 'author') %><%= link_to "Date Posted", articles_path(sort: 'date') %>
<%= link_to "#{article.title}", article %><%=article.author %><%=article.date %>
No articles found.
\ No newline at end of file diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb index 016fe2a0..638fccbc 100644 --- a/app/views/articles/index.html.erb +++ b/app/views/articles/index.html.erb @@ -1,34 +1,5 @@ -

<%= notice %>

Articles

- - - - - - - - - - - - <% if @articles.present? %> - <% @articles.each do |article| %> - - - - - - <% end %> - <% else %> - - - - <% end %> - -
<%= link_to "Title", articles_path(sort: 'title') %><%= link_to "Author", articles_path(sort: 'author') %><%= link_to "Date", articles_path(sort: 'date') %>
<%= link_to "#{article.title}", article %><%=article.author %><%=article.date %>
No articles found.
+<%= render "table" %> <%= link_to "New article", new_article_path, class:"btn btn-secondary" %> diff --git a/app/views/articles/search.html.erb b/app/views/articles/search.html.erb new file mode 100644 index 00000000..638fccbc --- /dev/null +++ b/app/views/articles/search.html.erb @@ -0,0 +1,5 @@ +

Articles

+ +<%= render "table" %> + +<%= link_to "New article", new_article_path, class:"btn btn-secondary" %> diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb index b95e0bfa..69b5f09a 100644 --- a/app/views/articles/show.html.erb +++ b/app/views/articles/show.html.erb @@ -1,5 +1,3 @@ -

<%= notice %>

- <%= render @article %>
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb index d088b498..0ae18027 100644 --- a/app/views/layouts/_navbar.html.erb +++ b/app/views/layouts/_navbar.html.erb @@ -18,17 +18,7 @@
diff --git a/app/views/layouts/_searchForm.html.erb b/app/views/layouts/_searchForm.html.erb new file mode 100644 index 00000000..2106a108 --- /dev/null +++ b/app/views/layouts/_searchForm.html.erb @@ -0,0 +1,4 @@ +<%= form_tag(article_search_path, method: 'get', class: "d-flex") do %> + <%= text_field_tag(:query, params[:query], class: "form-control me-2", placeholder: 'Search articles...') %> + <%= submit_tag('Search', class: "btn btn-outline-success") %> +<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index f66e4985..b021c186 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do get '/about', to: 'pages#about' + get '/articles/search', to: 'articles#search', as: 'article_search' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html resources :articles # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. diff --git a/test/controllers/articles_controller_test.rb b/test/controllers/articles_controller_test.rb index c81ec881..4b0918e8 100644 --- a/test/controllers/articles_controller_test.rb +++ b/test/controllers/articles_controller_test.rb @@ -2,7 +2,12 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest setup do - @article = articles(:one) + @article = Article.create( + title: 'First Post', + content: 'My first article for Shopify', + author: 'Maria Stringy', + date: Date.today + ) end test "should get index" do diff --git a/test/fixtures/articles.yml b/test/fixtures/articles.yml deleted file mode 100644 index 67aa23dd..00000000 --- a/test/fixtures/articles.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html - -one: - title: MyStringg - content: MyText - author: MyStringg - date: 2024-01-25 - -two: - title: MyString1 - content: MyText1 - author: MyString2 - date: 2024-01-25 From 9baa08d85f93f31bee2b8366849f6d612d3f4529 Mon Sep 17 00:00:00 2001 From: Emmanuel Idun <139833097+eidun10@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:29:32 -0600 Subject: [PATCH 5/6] Documentation and added tests (#6) * make title and content required * added tests * nit: code format --- app/controllers/articles_controller.rb | 2 +- app/models/article.rb | 4 ++ config/routes.rb | 6 ++- test/controllers/articles_controller_test.rb | 16 +++--- test/controllers/pages_controller_test.rb | 4 +- test/models/article_test.rb | 53 ++++++++++++++------ 6 files changed, 57 insertions(+), 28 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 04c24b99..c95e8a79 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -96,7 +96,7 @@ def set_article @article = Article.find(params[:id]) end - # Tggle between ascending order and descending order + # Toggle between ascending order and descending order def toggle_order(order) order == 'asc' ? 'desc' : 'asc' end diff --git a/app/models/article.rb b/app/models/article.rb index 263d7830..df77f7c2 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -1,4 +1,8 @@ class Article < ApplicationRecord + validates :title, presence: true + validates :content, presence: true + + # perform case-insentitive search on title or content of articles def self.search(query) where("title LIKE ? OR content LIKE ?", "%#{query}%", "%#{query}%") end diff --git a/config/routes.rb b/config/routes.rb index b021c186..eb49abdc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,10 @@ Rails.application.routes.draw do - get '/about', to: 'pages#about' - get '/articles/search', to: 'articles#search', as: 'article_search' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html resources :articles + + get '/about', to: 'pages#about' + get '/articles/search', to: 'articles#search', as: 'article_search' + # 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 diff --git a/test/controllers/articles_controller_test.rb b/test/controllers/articles_controller_test.rb index 4b0918e8..6fe159b4 100644 --- a/test/controllers/articles_controller_test.rb +++ b/test/controllers/articles_controller_test.rb @@ -12,12 +12,12 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest test "should get index" do get articles_url - assert_response :success + assert_response :success, 'Failed to get the index page.' end test "should get new" do get new_article_url - assert_response :success + assert_response :success, 'Failed to get the new article page.' end test "should create article" do @@ -25,29 +25,29 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest post articles_url, params: { article: { author: @article.author, content: @article.content, date: @article.date, title: @article.title } } end - assert_redirected_to article_url(Article.last) + assert_redirected_to article_url(Article.last), 'Article was not successfully created.' end test "should show article" do get article_url(@article) - assert_response :success + assert_response :success, 'Failed to get the article show page.' end test "should get edit" do get edit_article_url(@article) - assert_response :success + assert_response :success, 'Failed to get the edit article page.' end test "should update article" do patch article_url(@article), params: { article: { author: @article.author, content: @article.content, date: @article.date, title: @article.title } } - assert_redirected_to article_url(@article) + assert_redirected_to article_url(@article), 'Article was not successfully updated.' end test "should destroy article" do - assert_difference("Article.count", -1) do + assert_difference("Article.count", -1, 'Article destruction failed.') do delete article_url(@article) end - assert_redirected_to articles_url + assert_redirected_to articles_url, 'Article was not successfully destroyed.' end end diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb index 82565a8a..eda63bec 100644 --- a/test/controllers/pages_controller_test.rb +++ b/test/controllers/pages_controller_test.rb @@ -3,11 +3,11 @@ class PagesControllerTest < ActionDispatch::IntegrationTest test "should get home" do get root_url - assert_response :success + assert_response :success, 'Failed to get the home page.' end test "should get about" do get about_url - assert_response :success + assert_response :success, 'Failed to get the about page.' end end diff --git a/test/models/article_test.rb b/test/models/article_test.rb index 0d55b70e..42895ee9 100644 --- a/test/models/article_test.rb +++ b/test/models/article_test.rb @@ -2,67 +2,90 @@ class ArticleTest < ActiveSupport::TestCase test 'starts with no articles' do - assert_equal 0, Article.count + assert_equal 0, Article.count, 'Database should start with zero articles.' end test 'has search functionality' do - assert_respond_to Article, :search + assert_respond_to Article, :search, 'Article model should respond to the search method.' end test 'creates a new article' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') - assert article.valid? + assert article.valid?, "Article creation failed: #{article.errors.full_messages.join(', ')}" + end + + test 'requires a title and content' do + article = Article.new + assert_not article.valid? + assert_includes article.errors[:title], "can't be blank" + assert_includes article.errors[:content], "can't be blank" end test 'displays the article content accurately' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') - assert_equal 'Lorem ipsum dolor sit amet.', article.content + assert_equal 'Lorem ipsum dolor sit amet.', article.content, "Article content does not match: #{article.errors.full_messages.join(', ')}" end test 'displays the article metadata correctly' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.', author: 'John Doe', date: Date.today) - assert_equal 'John Doe', article.author - assert_equal Date.today, article.date + assert_equal 'John Doe', article.author, "Article author does not match: #{article.errors.full_messages.join(', ')}" + assert_equal Date.today, article.date, "Article date does not match: #{article.errors.full_messages.join(', ')}" end test 'edits an existing article' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') article.update(content: 'Updated content') - assert_equal 'Updated content', article.content + assert_equal 'Updated content', article.content, "Article content was not updated: #{article.errors.full_messages.join(', ')}" end test 'updates the article metadata' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.', author: 'John Doe', date: Date.today) article.update(author: 'Jane Smith', date: Date.yesterday) - assert_equal 'Jane Smith', article.author - assert_equal Date.yesterday, article.date + assert_equal 'Jane Smith', article.author, "Article author was not updated: #{article.errors.full_messages.join(', ')}" + assert_equal Date.yesterday, article.date, "Article date was not updated: #{article.errors.full_messages.join(', ')}" end test 'deletes an article' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') article.destroy - assert_equal 0, Article.count + assert_equal 0, Article.count, "Article was not successfully deleted: #{article.errors.full_messages.join(', ')}" end test 'prevents access to deleted articles' do article = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') article.destroy - assert_raises(ActiveRecord::RecordNotFound) { Article.find(article.id) } + assert_raises(ActiveRecord::RecordNotFound, 'Accessing deleted article should raise ActiveRecord::RecordNotFound') { Article.find(article.id) } end test 'returns accurate search results' do article1 = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') article2 = Article.create(title: 'Another Article', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.') results = Article.search('Lorem ipsum') - assert_includes results, article1 - assert_includes results, article2 + assert_includes results, article1, "Search results should include article1: #{article1.errors.full_messages.join(', ')}" + assert_includes results, article2, "Search results should include article2: #{article2.errors.full_messages.join(', ')}" end test 'displays relevant articles in search results' do article1 = Article.create(title: 'Sample Article', content: 'Lorem ipsum dolor sit amet.') article2 = Article.create(title: 'Another Article', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.') results = Article.search('Another') - assert_includes results, article2 - assert_not_includes results, article1 + assert_includes results, article2, "Search results should include article2 when searching for 'Another': #{article2.errors.full_messages.join(', ')}" + assert_not_includes results, article1, "Search results should not include article1 when searching for 'Another': #{article1.errors.full_messages.join(', ')}" + end + + test 'performs case-insensitive search' do + article = Article.create(title: 'Case Insensitive', content: 'Lorem ipsum dolor sit amet.') + results = Article.search('case insensitive') + assert_includes results, article + end + + test 'returns no results for empty search' do + results = Article.search('') + assert_empty results + end + + test 'returns no results for non-existing term' do + results = Article.search('NonExisting') + assert_empty results end end From b456cc0017e72528b4580f56d272cc26d496f36e Mon Sep 17 00:00:00 2001 From: Emmanuel Idun Date: Mon, 29 Jan 2024 22:49:26 -0600 Subject: [PATCH 6/6] bug fix --- test/system/articles_test.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/system/articles_test.rb b/test/system/articles_test.rb index 3e8a6ba6..7014628f 100644 --- a/test/system/articles_test.rb +++ b/test/system/articles_test.rb @@ -2,7 +2,12 @@ class ArticlesTest < ApplicationSystemTestCase setup do - @article = articles(:one) + @article = Article.create( + title: 'First Post', + content: 'My first article for Shopify', + author: 'Maria Stringy', + date: Date.today + ) end test "visiting the index" do