Skip to content

Commit

Permalink
add category
Browse files Browse the repository at this point in the history
* gem group reorg
* add factory_bot gem
* ignore byebug history
* ignore i18n cop
* add GH action for CI
* set categories#index as default route
* enable command line JS driver setting

foo
  • Loading branch information
agilous committed Dec 30, 2023
1 parent baabf0f commit 2ef4cb4
Show file tree
Hide file tree
Showing 35 changed files with 625 additions and 14 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: "CI"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:12-alpine
ports:
- "5432:5432"
env:
POSTGRES_DB: rails_test
POSTGRES_USER: rails
POSTGRES_PASSWORD: password
env:
RAILS_ENV: test
DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test"
steps:
- name: Checkout code
uses: actions/checkout@v3
# Add or replace dependency steps here
- name: Install Ruby and gems
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
# Add or replace database setup steps here
- name: Set up database schema
run: bin/rails db:schema:load
# Add or replace test runners here
- name: Run specs
run: bin/rspec

lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Ruby and gems
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
# Add or replace any other lints here
- name: Security audit application code
run: bin/brakeman
- name: Lint Ruby files
run: bin/rubocop --parallel
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@

# Ignore master key for decrypting credentials and more.
/config/master.key

.byebug_history
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-performance
- rubocop-rspec
- rubocop-rails
Expand All @@ -14,5 +15,8 @@ AllCops:
- lib/tasks/*
NewCops: enable

Rails/I18nLocaleTexts:
Enabled: false

Style/Documentation:
Enabled: false
1 change: 0 additions & 1 deletion .ruby-version

This file was deleted.

16 changes: 9 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ gem 'tzinfo-data', platforms: %i[windows jruby]
group :development, :test do
gem 'brakeman'
gem 'byebug', platforms: %i[mri mingw x64_mingw]
gem 'rspec-rails'
gem 'rubocop', require: false
gem 'rubocop-capybara', require: false
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
end

group :development do
Expand All @@ -32,5 +26,13 @@ end

group :test do
gem 'capybara'
gem 'selenium-webdriver'
gem 'factory_bot_rails'
gem 'rspec-rails'
gem 'rubocop', require: false
gem 'rubocop-capybara', require: false
gem 'rubocop-factory_bot', require: false
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
gem 'webdrivers'
end
15 changes: 13 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ GEM
drb (2.2.0)
ruby2_keywords
erubi (1.12.0)
factory_bot (6.4.4)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.2)
factory_bot (~> 6.4)
railties (>= 5.0.0)
globalid (1.2.1)
activesupport (>= 6.1)
i18n (1.14.1)
Expand Down Expand Up @@ -262,7 +267,7 @@ GEM
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
selenium-webdriver (4.16.0)
selenium-webdriver (4.10.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
Expand Down Expand Up @@ -290,6 +295,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webdrivers (5.3.1)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0, < 4.11)
webrick (1.8.1)
websocket (1.2.10)
websocket-driver (0.7.6)
Expand All @@ -309,6 +318,7 @@ DEPENDENCIES
brakeman
byebug
capybara
factory_bot_rails
importmap-rails
jbuilder
pg (~> 1.1)
Expand All @@ -317,15 +327,16 @@ DEPENDENCIES
rspec-rails
rubocop
rubocop-capybara
rubocop-factory_bot
rubocop-performance
rubocop-rails
rubocop-rspec
selenium-webdriver
sprockets-rails
stimulus-rails
turbo-rails
tzinfo-data
web-console
webdrivers

RUBY VERSION
ruby 3.2.2p53
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# TransactionCategorization Rails App
A simple [Rails](https://rubyonrails.org/) application that categorizes banking transaction via Machine Learning (AI).

![Build Status](https://github.com/agilous/transcat/actions/workflows/ci.yml/badge.svg)

## Dependencies
* [asdf](https://asdf-vm.com/#/)
* [Ruby](https://www.ruby-lang.org/en/) 3.2.2
Expand Down
Empty file added app/assets/images/.keep
Empty file.
71 changes: 71 additions & 0 deletions app/controllers/categories_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

class CategoriesController < ApplicationController
before_action :set_category, only: %i[show edit update destroy]

# GET /categories or /categories.json
def index
@categories = Category.all
end

# GET /categories/1 or /categories/1.json
def show; end

# GET /categories/new
def new
@category = Category.new
end

# GET /categories/1/edit
def edit; end

# POST /categories or /categories.json
def create
@category = Category.new(category_params)

respond_to do |format|
if @category.save
format.html { redirect_to category_url(@category), notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: @category }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /categories/1 or /categories/1.json
def update
respond_to do |format|
if @category.update(category_params)
format.html { redirect_to category_url(@category), notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: @category }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end

# DELETE /categories/1 or /categories/1.json
def destroy
@category.destroy!

respond_to do |format|
format.html { redirect_to categories_url, notice: 'Category was successfully destroyed.' }
format.json { head :no_content }
end
end

private

# Use callbacks to share common setup or constraints between actions.
def set_category
@category = Category.find(params[:id])
end

# Only allow a list of trusted parameters through.
def category_params
params.require(:category).permit(:name)
end
end
4 changes: 4 additions & 0 deletions app/helpers/categories_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

module CategoriesHelper
end
5 changes: 5 additions & 0 deletions app/models/category.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class Category < ApplicationRecord
validates :name, uniqueness: true, presence: true
end
7 changes: 7 additions & 0 deletions app/views/categories/_category.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div id="<%= dom_id category %>">
<p>
<strong>Name:</strong>
<%= category.name %>
</p>

</div>
4 changes: 4 additions & 0 deletions app/views/categories/_category.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.extract! category, :id, :name, :created_at, :updated_at
json.url category_url(category, format: :json)
22 changes: 22 additions & 0 deletions app/views/categories/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%= form_with(model: category) do |form| %>
<% if category.errors.any? %>
<div style="color: red">
<h2><%= pluralize(category.errors.count, "error") %> prohibited this category from being saved:</h2>

<ul>
<% category.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :name, style: "display: block" %>
<%= form.text_field :name %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
10 changes: 10 additions & 0 deletions app/views/categories/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Editing category</h1>

<%= render "form", category: @category %>

<br>

<div>
<%= link_to "Show this category", @category %> |
<%= link_to "Back to categories", categories_path %>
</div>
14 changes: 14 additions & 0 deletions app/views/categories/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<h1>Categories</h1>

<div id="categories">
<% @categories.each do |category| %>
<%= render category %>
<p>
<%= link_to "Show this category", category %>
</p>
<% end %>
</div>

<%= link_to "New category", new_category_path %>
3 changes: 3 additions & 0 deletions app/views/categories/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.array! @categories, partial: 'categories/category', as: :category
9 changes: 9 additions & 0 deletions app/views/categories/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>New category</h1>

<%= render "form", category: @category %>

<br>

<div>
<%= link_to "Back to categories", categories_path %>
</div>
10 changes: 10 additions & 0 deletions app/views/categories/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @category %>

<div>
<%= link_to "Edit this category", edit_category_path(@category) %> |
<%= link_to "Back to categories", categories_path %>

<%= button_to "Destroy this category", @category, method: :delete %>
</div>
3 changes: 3 additions & 0 deletions app/views/categories/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.partial! 'categories/category', category: @category
27 changes: 27 additions & 0 deletions bin/brakeman
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

#
# This file was generated by Bundler.
#
# The application 'brakeman' is installed as part of a gem, and
# this file is here to facilitate running it.
#

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

bundle_binstub = File.expand_path("bundle", __dir__)

if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end

require "rubygems"
require "bundler/setup"

load Gem.bin_path("brakeman", "brakeman")
7 changes: 6 additions & 1 deletion bin/ci
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ Dir.chdir(APP_ROOT) do
ruby_linting_passed = system("bin/rubocop")
terminal_message("Done.\n\n")

terminal_message("Running Brakeman Scan...")
brakeman_passed = system("bin/brakeman")
terminal_message("Done.\n\n")

pass_fail(ruby_tests_passed, "Ruby Tests")
pass_fail(ruby_linting_passed, "Ruby Linter")
pass_fail(brakeman_passed, "Brakeman Scan")

return 1 unless ruby_tests_passed && ruby_linting_passed
return 1 unless ruby_tests_passed && ruby_linting_passed && brakeman_passed

return 0
end
8 changes: 8 additions & 0 deletions config/brakeman.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
:rails3: false
:rails4: false
:rails5: false
:rails6: false
:rails7: true
:quiet: true
:summary_only: :no_summary
Loading

0 comments on commit 2ef4cb4

Please sign in to comment.