From cbb508206d61a0c5ef9c720b17cde854d650016c Mon Sep 17 00:00:00 2001
From: sharkby7e <37809009+sharkby7e@users.noreply.github.com>
Date: Mon, 30 Sep 2024 23:40:18 -0400
Subject: [PATCH] Associate tools to users (#2)
* add user_id to tools, set up associations and factories, and annotate gem
* tool index with user contact info
---
Gemfile | 1 +
Gemfile.lock | 4 ++
app/controllers/tools_controller.rb | 1 +
app/models/tool.rb | 14 +++++
app/models/user.rb | 35 +++++++++++
app/views/tools/index.html.erb | 23 ++++++-
config/environments/test.rb | 9 ++-
.../20241001014453_add_user_id_to_tools.rb | 7 +++
db/schema.rb | 3 +-
lib/tasks/auto_annotate_models.rake | 61 +++++++++++++++++++
spec/controllers/tools_controller_spec.rb | 16 ++++-
spec/factories.rb | 4 +-
spec/models/user_spec.rb | 6 +-
spec/rails_helper.rb | 3 +
14 files changed, 177 insertions(+), 10 deletions(-)
create mode 100644 db/migrate/20241001014453_add_user_id_to_tools.rb
create mode 100644 lib/tasks/auto_annotate_models.rake
diff --git a/Gemfile b/Gemfile
index 1f83267..bd8e78c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -28,6 +28,7 @@ gem 'tzinfo-data', platforms: %i[windows jruby]
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
+ gem 'annotate'
gem 'debug', platforms: %i[mri mingw x64_mingw]
gem 'factory_bot_rails'
gem 'faker'
diff --git a/Gemfile.lock b/Gemfile.lock
index a166c05..462d8e2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -89,6 +89,9 @@ GEM
tzinfo (~> 2.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
+ annotate (3.2.0)
+ activerecord (>= 3.2, < 8.0)
+ rake (>= 10.4, < 14.0)
base64 (0.2.0)
bcrypt (3.1.20)
bigdecimal (3.1.8)
@@ -367,6 +370,7 @@ PLATFORMS
x86_64-linux-musl
DEPENDENCIES
+ annotate
bootsnap
capybara
debug
diff --git a/app/controllers/tools_controller.rb b/app/controllers/tools_controller.rb
index 927f7f3..ed29fb7 100644
--- a/app/controllers/tools_controller.rb
+++ b/app/controllers/tools_controller.rb
@@ -2,5 +2,6 @@
class ToolsController < ApplicationController
def index
+ @tools = Tool.all
end
end
diff --git a/app/models/tool.rb b/app/models/tool.rb
index 699e743..0f0f546 100644
--- a/app/models/tool.rb
+++ b/app/models/tool.rb
@@ -1,4 +1,18 @@
# frozen_string_literal: true
class Tool < ApplicationRecord
+ belongs_to :user
end
+
+# == Schema Information
+#
+# Table name: tools
+#
+# id :integer not null, primary key
+# brand_name :string
+# description :text
+# name :string
+# created_at :datetime not null
+# updated_at :datetime not null
+# user_id :integer not null
+#
diff --git a/app/models/user.rb b/app/models/user.rb
index d1092c3..feec5d4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -6,4 +6,39 @@ class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable,
:trackable, :omniauthable
+
+ has_many :tools
end
+
+# == Schema Information
+#
+# Table name: users
+#
+# id :integer not null, primary key
+# confirmation_sent_at :datetime
+# confirmation_token :string
+# confirmed_at :datetime
+# current_sign_in_at :datetime
+# current_sign_in_ip :string
+# email :string default(""), not null
+# encrypted_password :string default(""), not null
+# failed_attempts :integer default(0), not null
+# last_sign_in_at :datetime
+# last_sign_in_ip :string
+# locked_at :datetime
+# remember_created_at :datetime
+# reset_password_sent_at :datetime
+# reset_password_token :string
+# sign_in_count :integer default(0), not null
+# unconfirmed_email :string
+# unlock_token :string
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+# Indexes
+#
+# index_users_on_confirmation_token (confirmation_token) UNIQUE
+# index_users_on_email (email) UNIQUE
+# index_users_on_reset_password_token (reset_password_token) UNIQUE
+# index_users_on_unlock_token (unlock_token) UNIQUE
+#
diff --git a/app/views/tools/index.html.erb b/app/views/tools/index.html.erb
index 300919f..15f6c99 100644
--- a/app/views/tools/index.html.erb
+++ b/app/views/tools/index.html.erb
@@ -1 +1,22 @@
-
Tools
+
+
Tools
+
+
+
+ Tool Name |
+ Tool Brand |
+ Owner Contact |
+
+
+
+
+ <% @tools.each do |tool| %>
+
+ <%= tool.name %> |
+ <%= tool.brand_name %> |
+ <%= mail_to tool.user.email %> |
+
+ <% end %>
+
+
+
diff --git a/config/environments/test.rb b/config/environments/test.rb
index adbb4a6..f085138 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -1,4 +1,6 @@
-require "active_support/core_ext/integer/time"
+# frozen_string_literal: true
+
+require 'active_support/core_ext/integer/time'
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
@@ -15,12 +17,12 @@
# this is usually not necessary, and can slow down your test suite. However, it's
# recommended that you enable it in continuous integration systems to ensure eager
# loading is working properly before deploying your code.
- config.eager_load = ENV["CI"].present?
+ config.eager_load = ENV['CI'].present?
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
- "Cache-Control" => "public, max-age=#{1.hour.to_i}"
+ 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.
@@ -43,6 +45,7 @@
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
+ Rails.application.routes.default_url_options[:host] = 'domain.example'
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
diff --git a/db/migrate/20241001014453_add_user_id_to_tools.rb b/db/migrate/20241001014453_add_user_id_to_tools.rb
new file mode 100644
index 0000000..16f0db4
--- /dev/null
+++ b/db/migrate/20241001014453_add_user_id_to_tools.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddUserIdToTools < ActiveRecord::Migration[7.1]
+ def change
+ add_column :tools, :user_id, :integer, null: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 52b2c6f..6fb966f 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_09_01_221122) do
+ActiveRecord::Schema[7.1].define(version: 2024_10_01_014453) do
create_table "tools", force: :cascade do |t|
t.string "name"
t.string "brand_name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.integer "user_id", null: false
end
create_table "users", force: :cascade do |t|
diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake
new file mode 100644
index 0000000..3d0afed
--- /dev/null
+++ b/lib/tasks/auto_annotate_models.rake
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+# NOTE: only doing this in development as some production environments (Heroku)
+# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
+# NOTE: to have a dev-mode tool do its thing in production.
+if Rails.env.development?
+ require 'annotate'
+ task :set_annotation_options do
+ # You can override any of these by setting an environment variable of the
+ # same name.
+ Annotate.set_defaults(
+ 'active_admin' => 'false',
+ 'additional_file_patterns' => [],
+ 'routes' => 'false',
+ 'models' => 'true',
+ 'position_in_routes' => 'before',
+ 'position_in_class' => 'after',
+ 'position_in_test' => 'before',
+ 'position_in_fixture' => 'before',
+ 'position_in_factory' => 'before',
+ 'position_in_serializer' => 'before',
+ 'show_foreign_keys' => 'true',
+ 'show_complete_foreign_keys' => 'false',
+ 'show_indexes' => 'true',
+ 'simple_indexes' => 'false',
+ 'model_dir' => 'app/models',
+ 'root_dir' => '',
+ 'include_version' => 'false',
+ 'require' => '',
+ 'exclude_tests' => 'true',
+ 'exclude_fixtures' => 'false',
+ 'exclude_factories' => 'false',
+ 'exclude_serializers' => 'false',
+ 'exclude_scaffolds' => 'true',
+ 'exclude_controllers' => 'true',
+ 'exclude_helpers' => 'true',
+ 'exclude_sti_subclasses' => 'false',
+ 'ignore_model_sub_dir' => 'false',
+ 'ignore_columns' => nil,
+ 'ignore_routes' => nil,
+ 'ignore_unknown_models' => 'false',
+ 'hide_limit_column_types' => 'integer,bigint,boolean',
+ 'hide_default_column_types' => 'json,jsonb,hstore',
+ 'skip_on_db_migrate' => 'false',
+ 'format_bare' => 'true',
+ 'format_rdoc' => 'false',
+ 'format_yard' => 'false',
+ 'format_markdown' => 'false',
+ 'sort' => 'false',
+ 'force' => 'false',
+ 'frozen' => 'false',
+ 'classified_sort' => 'true',
+ 'trace' => 'false',
+ 'wrapper_open' => nil,
+ 'wrapper_close' => nil,
+ 'with_comment' => 'true'
+ )
+ end
+
+ Annotate.load_tasks
+end
diff --git a/spec/controllers/tools_controller_spec.rb b/spec/controllers/tools_controller_spec.rb
index d052420..1e7e011 100644
--- a/spec/controllers/tools_controller_spec.rb
+++ b/spec/controllers/tools_controller_spec.rb
@@ -2,12 +2,22 @@
require 'rails_helper'
-RSpec.describe ToolsController, type: :controller do
- describe 'GET /index' do
+RSpec.describe ToolsController, type: :request do
+ describe '#index' do
+ let!(:tool) { create(:tool) }
+
it 'works' do
- get :index
+ get tools_path
+
+ expect(response).to be_successful
+ end
+
+ it 'includes info about the tool' do
+ get tools_path
expect(response).to be_successful
+ expect(response.body).to have_content(tool.name)
+ expect(response.body).to have_content tool.user.email
end
end
end
diff --git a/spec/factories.rb b/spec/factories.rb
index aca1a4a..8b4f041 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -2,10 +2,12 @@
FactoryBot.define do
factory :user do
-
+ email { 'finch@keating.com' }
+ password { 'catnip' }
end
factory(:tool) do
+ association :user
name { 'Hammer' }
brand_name { 'Makita' }
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 47a31bb..20be96e 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1,5 +1,9 @@
+# frozen_string_literal: true
+
require 'rails_helper'
RSpec.describe User, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ it 'has a valid factory' do
+ expect(build(:user)).to be_valid
+ end
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index a551ab7..886b07e 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -63,6 +63,9 @@
# https://rspec.info/features/6-0/rspec-rails
config.infer_spec_type_from_file_location!
+ # have_content etc...
+ config.include Capybara::RSpecMatchers, type: :request
+
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via: