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 Engineering Technical Challenge #301

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.3
ruby-version: 3.3.0
bundler-cache: true

- name: Run tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -33,3 +33,4 @@

# Ignore master key for decrypting credentials and more.
/config/master.key
.DS_Store
2 changes: 1 addition & 1 deletion .ruby-version
@@ -1 +1 @@
3.2.3
3.3.0
2 changes: 1 addition & 1 deletion 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"
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Expand Up @@ -238,7 +238,7 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webdrivers (5.3.1)
webdrivers (5.3.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0, < 4.11)
Expand Down Expand Up @@ -276,7 +276,7 @@ DEPENDENCIES
webdrivers

RUBY VERSION
ruby 3.2.3p157
ruby 3.3.0p0

BUNDLED WITH
2.5.5
68 changes: 20 additions & 48 deletions README.md
@@ -1,55 +1,27 @@
# Technical Instructions
1. Fork this repo to your local Github account.
2. Create a new branch to complete all your work in.
3. Test your work using the provided tests
4. Create a Pull Request against the Shopify Main branch when you're done and all tests are passing
# Shopify Engineering Internships Backend Technical Challenge
This is a Ruby on Rails Application created for Shopify's Engineering Internship Program 2024.

# Project Overview
The Rails application you will be working on is an Encyclopedia, which allows users to create, view, edit, and delete articles. The application also provides search functionality to help users find relevant articles. Be sure to implement basic CRUD actions on articles. Your task is to implement these features as well as write the code that makes the tests pass.

# Project Goals
The main goal of this internship project is to implement the functionality required to make the existing tests pass. The provided tests cover various aspects of the application, including creating and viewing articles, editing and updating articles, deleting articles, and searching for articles. Along with completing the tests, be sure to implement all basic CRUD actions on your articles on a controller and create views to see your work in the app.

## Your specific goals for this project are as follows:

1. Review Existing Tests: Start by reviewing the existing tests provided in the article_test.rb file located in the test/models directory. Understand the requirements and expectations of each test.

2. Implement Functionality: Write the code necessary to make the existing tests pass. This involves implementing the required actions and logic in the models, controllers, and views to fulfill the specified requirements. Also be sure to implement basic CRUD actions and demonstrate proper MVC principals.

3. Ensure Code Quality: Write clean, well-structured, and maintainable code. Follow best practices and adhere to the Ruby on Rails conventions. Pay attention to code readability, modularity, and performance.

4. Test Your Code: After implementing the functionality, run the tests to ensure that they pass successfully. Fix any failures or errors that occur and retest until all tests pass.

5. Code Documentation: Document your code by adding comments and explanatory notes where necessary. This will help other developers understand your implementation and make future maintenance easier.

6. Version Control: Use Git for version control. Commit your changes regularly and push them to a branch in your forked repository.

7. Create a Pull Request: Once you have completed the project goals, create a pull request to merge your changes into the main repository. Provide a clear description of the changes made and any relevant information for the code review.
The Rails application is an implementation of an Encyclopedia, which allows users to create, view, edit, and delete articles. The application also provides search functionality to help users find relevant articles.

## Getting Started
To get started with this project, follow these steps:

1. Clone the repository to your local development environment.

2. Install the necessary dependencies by running bundle install in the project directory.

3. Familiarize yourself with the existing codebase, including the models, controllers, and views.

4. Review the existing tests in the article_test.rb file and understand their purpose and functionality.

5. Run the tests locally to ensure they are passing.

6. Start working on the goals outlined above, making improvements to the existing tests and adding new tests as needed.

7. Commit your changes regularly and push them to a branch in your forked repository.

8. Once you have completed the project goals, create a pull request to merge your changes into the main repository.

## Resources
Here are some resources that may be helpful during your internship project:

- [Ruby on Rails Guides](https://guides.rubyonrails.org/) - Comprehensive guides on Ruby on Rails, covering various aspects of web application development.

- [Ruby Style Guide](https://rubystyle.guide/) - A community-driven Ruby coding style guide to ensure consistent and readable code.

- [Git Documentation](https://git-scm.com/doc) - Official documentation for Git, the version control system used in this project.
2. You will need to install Ruby and SQLite3
3. Install the necessary dependencies by running bundle install in the project directory.
```
bundle install
```
3. Run the server in the application directory in the terminal

```
bin/rails server
```
4. Go to localhost:3000 to view the app

5. To run the test suite

```
bin/rails test
```
62 changes: 62 additions & 0 deletions app/controllers/articles_controller.rb
@@ -0,0 +1,62 @@
class ArticlesController < ApplicationController

def index
@articles = Article.all
end

# searches for an article
def search
@articles = if params[:q]
Article.search(params[:q])
end
end

# show a single article
def show
@article = Article.find(params[:id])
end

# create a new article
def new
@article = Article.new
end

# post a new article
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

# updates existing article
def update
@article = Article.find(params[:id])

if @article.update(article_params)
redirect_to @article
else
render :edit, status: :unprocessable_entity
end
end

# destroys an article
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, :content, :author, :date)
end
end
2 changes: 2 additions & 0 deletions app/helpers/articles_helper.rb
@@ -0,0 +1,2 @@
module ArticlesHelper
end
12 changes: 12 additions & 0 deletions app/models/article.rb
@@ -0,0 +1,12 @@
class Article < ApplicationRecord
validates :title, presence: true, length: {minimum: 1 }
validates :content, presence: true, length: { minimum: 10 }
validates :author, presence: false
validates :date, presence: false


def self.search(q)
return Article.where("title LIKE ? OR content LIKE ? OR author LIKE ?",
"%" + q + "%", "%" + q + "%", "%" + q + "%")
end
end
38 changes: 38 additions & 0 deletions app/views/articles/_form.html.erb
@@ -0,0 +1,38 @@
<%= form_with model: article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% article.errors.full_messages_for(:title).each do |message| %>
<div><%= message %></div>
<% end %>
</div>

<div>
<%= form.label :content %><br>
<%= form.text_area :content %><br>
<% article.errors.full_messages_for(:content).each do |message| %>
<div><%= message %></div>
<% end %>
</div>

<div>
<%= form.label :author %><br>
<%= form.text_field :author %>
<% article.errors.full_messages_for(:author).each do |message| %>
<div><%= message %></div>
<% end %>
</div>

<div>
<%= form.label :date %><br>
<%= form.date_select :date %>
<% article.errors.full_messages_for(:date).each do |message| %>
<div><%= message %></div>
<% end %>
</div>

<div>
<br>
<%= form.submit %>
</div>
<% end %>
3 changes: 3 additions & 0 deletions app/views/articles/edit.html.erb
@@ -0,0 +1,3 @@
<h1>Edit Article</h1>

<%= render "form", article: @article %>
11 changes: 11 additions & 0 deletions app/views/articles/index.html.erb
@@ -0,0 +1,11 @@
<h1>Articles</h1>

<ul>
<% @articles.each do |article| %>
<li>
<%= link_to article.title, article %>
</li>
<% end %>
</ul>

<%= link_to "New Article", new_article_path %>
3 changes: 3 additions & 0 deletions app/views/articles/new.html.erb
@@ -0,0 +1,3 @@
<h1>New Article</h1>

<%= render "form", article: @article %>
11 changes: 11 additions & 0 deletions app/views/articles/search.html.erb
@@ -0,0 +1,11 @@
<h1>Search Results</h1>

<% if @articles.present? %>
<ul>
<% @articles.each do |article| %>
<li><%= link_to article.title, article_path(article) %></li>
<% end %>
</ul>
<% else %>
<p>No articles found. Please try another search.</p>
<% end %>
16 changes: 16 additions & 0 deletions app/views/articles/show.html.erb
@@ -0,0 +1,16 @@
<h1><%= @article.title %></h1>

<p><%= @article.content %></p>

<p>By: <%= @article.author %></p>

<p><%= @article.date %></p>

<ul>
<li><%= link_to "Edit", edit_article_path(@article) %></li>
<li><%= link_to "Destroy", article_path(@article), data: {
turbo_method: :delete,
turbo_confirm: "Are you sure?"
} %></li>
<li><%= link_to "Home", "/" %></li>
</ul>
23 changes: 23 additions & 0 deletions app/views/home/_navbar.html.erb
@@ -0,0 +1,23 @@
<nav class="navbar navbar-expand-lg bg-body-secondary">
<div class="container-fluid">
<a class="navbar-brand">Encyclopedia App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/articles/new">New Article</a>
</li>
</ul>
<form class="d-flex" action="/search">
<input class="form-control me-2" name="q" type="search" placeholder="Search Articles" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
18 changes: 12 additions & 6 deletions app/views/layouts/application.html.erb
@@ -1,16 +1,22 @@
<!DOCTYPE html>
<html>
<!doctype html>
<html lang="en">
<head>
<title>EngInternAssessmentRails</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Encyclopedia App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

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

<body>
<%= render 'home/navbar'%>
<div class= "container">
<br/>
<%= yield %>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
</html>
8 changes: 7 additions & 1 deletion config/routes.rb
Expand Up @@ -6,5 +6,11 @@
get "up" => "rails/health#show", as: :rails_health_check

# Defines the root path route ("/")
# root "posts#index"
root "articles#index"

# route for search
get "search", to:"articles#search"

# resourceful routing - maps all conventional routes for Articles
resources :articles
end
12 changes: 12 additions & 0 deletions db/migrate/20240128005115_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
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.