Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backend Application - Shaan Suthar #311

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ gem "stimulus-rails"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"

# Bundle Shopify's Ruby style guide checker
gem "rubocop-shopify", require: false

# Bundle bootstrap for styling
#gem 'bootstrap', '~> 5.0'

# Use Redis adapter to run Action Cable in production
# gem "redis", ">= 4.0.1"

Expand Down
26 changes: 26 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ GEM
tzinfo (~> 2.0)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
base64 (0.2.0)
bigdecimal (3.1.6)
bindex (0.8.1)
Expand Down Expand Up @@ -117,6 +118,8 @@ GEM
jbuilder (2.11.5)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
json (2.7.1)
language_server-protocol (3.17.0.3)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand Down Expand Up @@ -153,6 +156,10 @@ GEM
racc (~> 1.4)
nokogiri (1.16.0-x86_64-linux)
racc (~> 1.4)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
psych (5.1.2)
stringio
public_suffix (5.0.4)
Expand Down Expand Up @@ -196,13 +203,30 @@ GEM
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.1.0)
rdoc (6.6.2)
psych (>= 4.0.0)
regexp_parser (2.9.0)
reline (0.4.2)
io-console (~> 0.5)
rexml (3.2.6)
rubocop (1.60.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
parser (>= 3.2.1.0)
rubocop-shopify (2.14.0)
rubocop (~> 1.51)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
selenium-webdriver (4.10.0)
Expand Down Expand Up @@ -233,6 +257,7 @@ GEM
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand Down Expand Up @@ -266,6 +291,7 @@ DEPENDENCIES
jbuilder
puma (>= 5.0)
rails (~> 7.1.2)
rubocop-shopify
selenium-webdriver
sprockets-rails
sqlite3 (~> 1.4)
Expand Down
69 changes: 69 additions & 0 deletions app/controllers/articles_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
class ArticlesController < ApplicationController
# Find the article to display for the show, edit, update and destroy actions
before_action :find_article, only: [:show, :edit, :update, :destroy]

# Display all articles in ascending order
def index
@articles = Articles.all
if params[:query].present?
@articles = Articles.search(params[:query]) # Search for articles based on the query
else
@articles = Articles.order(title: :asc) # Display all articles in ascending order
end
end

# Display a single article
def show
# Using before_action to find the article so no logic is needed here
end

# Create a new article
def new
@article = Articles.new
end

# Create a new article based on the form data
def create
@article = Articles.new(article_params)

# Try to save the article
if @article.save
redirect_to @article, notice: 'Article was created successfully' # Redirect to the article's page
else
render 'new' # Render the new article form again
end
end

# Edit an existing article
def edit
# Using before_action to find the article so no logic is needed here
end

# Update an existing article based on the form data
def update
# Try to update the article
if @article.update(article_params)
redirect_to @article, notice: 'Article was updated successfully' # Redirect to the article's page
else
render 'edit' # Render the edit article form again
end
end

# Delete an existing article
def destroy
@article.destroy
redirect_to root_path, notice: 'Article was deleted successfully' # Redirect to the articles page
end

private

# Define the parameters that can be passed to the article
def article_params
params.require(:article).permit(:title, :content, :author, :date)
end

# Find the article to display
def find_article
@article = Articles.find(params[:id])
end
end
6 changes: 6 additions & 0 deletions app/models/articles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Articles < ApplicationRecord
def self.search(query)
where("title LIKE ? OR content LIKE ?", "%#{query}%", "%#{query}%")
end
end

32 changes: 32 additions & 0 deletions app/views/articles/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<%= form_with(model: @article, local: true) do |form| %>
<% if @article.errors.any? %>
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading"><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h4>
<ul>
<% @article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="form-group mb-3">
<%= form.label :title, class: "form-label" %>
<%= form.text_field :title, class: "form-control" %>
</div>

<div class="form-group mb-3">
<%= form.label :content, class: "form-label" %>
<%= form.text_area :content, class: "form-control", rows: 5 %>
</div>

<div class="form-group mb-3">
<%= form.label :author, class: "form-label" %>
<%= form.text_field :author, class: "form-control" %>
</div>

<div class="form-group">
<%= form.submit 'Save Article', class: 'btn btn-primary' %>
</div>
<% end %>

21 changes: 21 additions & 0 deletions app/views/articles/delete.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
Confirm Deletion
</div>
<div class="card-body">
<h5 class="card-title">Are you sure you want to delete this article?</h5>
<p class="card-text">Title: <%= @article.title %></p>
<p class="card-text">Author: <%= @article.author %></p>

<%= form_with(model: @article, method: :delete) do |form| %>
<%= form.submit "Yes, Delete", class: "btn btn-danger" %>
<%= link_to "Cancel", article_path(@article), class: "btn btn-secondary" %>
<% end %>
</div>
</div>
</div>
</div>
</div>
5 changes: 5 additions & 0 deletions app/views/articles/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>Edit Article</h1>

<%= render 'form' %>

<%= link_to 'Back', root_path, class: 'btn btn-secondary mt-3' %>
27 changes: 27 additions & 0 deletions app/views/articles/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="container">
<h1 class="my-4">Articles</h1>

<%= form_tag(articles_path, method: :get, class: "form-inline mb-3") do %>
<div class="input-group">
<%= text_field_tag :query, params[:query], placeholder: "Search articles...", class: "form-control mr-sm-2", type: "search" %>
<div class="input-group-append">
<%= submit_tag "Search", class: "btn btn-primary" %>
</div>
</div>
<% end %>

<% @articles.each do |article| %>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">
<%= link_to article.title, article_path(article) %>
</h5>
<%= link_to 'Read More', article_path(article), class: 'btn btn-primary mr-2' %>
<%= link_to 'Edit', edit_article_path(article), class: 'btn btn-info mr-2' %>
<%= link_to 'Delete', article_path(article), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' %>
</div>
</div>
<% end %>

<%= link_to 'New Article', new_article_path, class: 'btn btn-success mt-3' %>
</div>
28 changes: 28 additions & 0 deletions app/views/articles/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<div class="container">
<h1 class="my-4">New Article</h1>

<%= form_with(model: @article, url: articles_path, html: { class: 'needs-validation' }, local: true) do |form| %>

<div class="form-group mb-3">
<%= form.label :title, class: 'form-label' %>
<%= form.text_field :title, class: 'form-control' %>
</div>

<div class="form-group mb-3">
<%= form.label :author, class: 'form-label' %>
<%= form.text_field :author, class: 'form-control' %>
</div>

<div class="form-group mb-3">
<%= form.label :content, class: 'form-label' %>
<%= form.text_area :content, class: 'form-control', rows: 5 %>
</div>

<div class="actions">
<%= form.submit 'Create Article', class: 'btn btn-primary' %>
</div>

<% end %>

<%= link_to 'Back', root_path, class: 'btn btn-secondary mt-3' %>
</div>
16 changes: 16 additions & 0 deletions app/views/articles/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="container">
<h1 class="my-4"><%= @article.title %></h1>

<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Author: <%= @article.author %></h5>
<p class="card-text"><%= @article.content %></p>
</div>
</div>

<div>
<%= link_to 'Edit', edit_article_path(@article), class: 'btn btn-primary me-2' %>
<%= link_to 'Delete', article_path(@article), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger me-2' %>
<%= link_to 'Back', root_path, class: 'btn btn-secondary' %>
</div>
</div>
12 changes: 10 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>

<body>
<%= yield %>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<%= link_to "EngInternAssessmentRails", root_path, class: "navbar-brand" %>
<!-- Other navigation links can go here -->
</div>
</nav>

<div class="container mt-3">
<%= yield %>
</div>
</body>
</html>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@

# Defines the root path route ("/")
# root "posts#index"
resources :articles
root "articles#index"
end
11 changes: 11 additions & 0 deletions db/migrate/20240130043137_create_articles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
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
23 changes: 23 additions & 0 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.