From 34d446e64179daf22e37bc6ee4479753503a0421 Mon Sep 17 00:00:00 2001 From: Travis Dockter Date: Sun, 27 Jul 2025 17:50:50 -0600 Subject: [PATCH 1/3] Working heatmap --- app/controllers/charts_controller.rb | 12 +++++ app/views/charts/heatmap.html.haml | 71 +++++++++++++++++++++++++ app/views/layouts/application.html.haml | 3 ++ config/routes.rb | 6 ++- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 app/views/charts/heatmap.html.haml diff --git a/app/controllers/charts_controller.rb b/app/controllers/charts_controller.rb index 7b82f3a..4e1fe99 100644 --- a/app/controllers/charts_controller.rb +++ b/app/controllers/charts_controller.rb @@ -23,6 +23,18 @@ def show end end + def heatmap + @available_years = current_user.entries + .pluck(Arel.sql("DISTINCT strftime('%Y', date)")) + .compact + .sort + .reverse + + @selected_year = params[:year] || @available_years.first || Date.current.year.to_s + + @heatmap_data = calculate_daily_expenses(@selected_year) + end + private def calculate_monthly_profit_loss(year) diff --git a/app/views/charts/heatmap.html.haml b/app/views/charts/heatmap.html.haml new file mode 100644 index 0000000..627b9cc --- /dev/null +++ b/app/views/charts/heatmap.html.haml @@ -0,0 +1,71 @@ +%h1 Expense Heatmap + +.heatmap-controls + = form_with url: heatmap_charts_path, method: :get, data: { turbo_frame: 'heatmap_content' } do |f| + = f.label :year, 'Select Year:' + = f.select :year, options_for_select(@available_years, @selected_year), {}, { onchange: 'this.form.requestSubmit()' } + += turbo_frame_tag 'heatmap_content' do + .heatmap-container + %h2 Daily Expenses - #{@selected_year} + .heatmap-legend + %span.legend-label Low + .legend-gradient + %span.legend-label High + %span.legend-max= "(Max: #{number_to_currency(@heatmap_data[:max_expense])})" + + .heatmap-wrapper{ + data: { + controller: 'heatmap', + 'heatmap-data-value': @heatmap_data.to_json + } + } + %svg#expense-heatmap{ width: '100%', height: '170', viewBox: '0 0 954 170' } + +%style + :css + .heatmap-container { + margin: 20px 0; + } + + .heatmap-controls { + margin-bottom: 20px; + } + + .heatmap-legend { + display: flex; + align-items: center; + margin-bottom: 15px; + gap: 10px; + } + + .legend-gradient { + width: 200px; + height: 20px; + background: linear-gradient(to right, #f0f0f0, #fee, #fcc, #f99, #f66, #f33, #c00); + border: 1px solid #ddd; + border-radius: 3px; + } + + .legend-label { + font-size: 12px; + color: #666; + } + + .legend-max { + margin-left: 10px; + font-size: 12px; + color: #666; + } + + .heatmap-wrapper { + overflow-x: auto; + padding: 10px; + background: white; + border-radius: 5px; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + } + + #expense-heatmap { + min-width: 954px; + } \ No newline at end of file diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index f0fea8c..70b9a00 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -57,6 +57,9 @@ %li %a{ href: charts_path } Charts + %li + %a{ href: heatmap_charts_path } + Heatmap %li %a{ href: edit_user_path(current_user) } Account diff --git a/config/routes.rb b/config/routes.rb index 9bef0e4..db33494 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,7 +24,11 @@ post '/dashboard', to: 'dashboards#show' # Charts - resource :charts, only: [:show] + resource :charts, only: [:show] do + member do + get 'heatmap' + end + end # Authentication routes resource :session From 367bd4b04f98267940a437d5c0e452c2252220e3 Mon Sep 17 00:00:00 2001 From: Travis Dockter Date: Sun, 27 Jul 2025 18:08:01 -0600 Subject: [PATCH 2/3] Move heatmap to charts page with tabs --- app/controllers/charts_controller.rb | 14 ++--- app/views/charts/heatmap.html.haml | 71 ------------------------- app/views/charts/show.html.haml | 2 +- app/views/layouts/application.html.haml | 3 -- config/routes.rb | 6 +-- 5 files changed, 6 insertions(+), 90 deletions(-) delete mode 100644 app/views/charts/heatmap.html.haml diff --git a/app/controllers/charts_controller.rb b/app/controllers/charts_controller.rb index 4e1fe99..4dbe393 100644 --- a/app/controllers/charts_controller.rb +++ b/app/controllers/charts_controller.rb @@ -23,16 +23,10 @@ def show end end - def heatmap - @available_years = current_user.entries - .pluck(Arel.sql("DISTINCT strftime('%Y', date)")) - .compact - .sort - .reverse - - @selected_year = params[:year] || @available_years.first || Date.current.year.to_s - - @heatmap_data = calculate_daily_expenses(@selected_year) + respond_to do |format| + format.html + format.turbo_stream + end end private diff --git a/app/views/charts/heatmap.html.haml b/app/views/charts/heatmap.html.haml deleted file mode 100644 index 627b9cc..0000000 --- a/app/views/charts/heatmap.html.haml +++ /dev/null @@ -1,71 +0,0 @@ -%h1 Expense Heatmap - -.heatmap-controls - = form_with url: heatmap_charts_path, method: :get, data: { turbo_frame: 'heatmap_content' } do |f| - = f.label :year, 'Select Year:' - = f.select :year, options_for_select(@available_years, @selected_year), {}, { onchange: 'this.form.requestSubmit()' } - -= turbo_frame_tag 'heatmap_content' do - .heatmap-container - %h2 Daily Expenses - #{@selected_year} - .heatmap-legend - %span.legend-label Low - .legend-gradient - %span.legend-label High - %span.legend-max= "(Max: #{number_to_currency(@heatmap_data[:max_expense])})" - - .heatmap-wrapper{ - data: { - controller: 'heatmap', - 'heatmap-data-value': @heatmap_data.to_json - } - } - %svg#expense-heatmap{ width: '100%', height: '170', viewBox: '0 0 954 170' } - -%style - :css - .heatmap-container { - margin: 20px 0; - } - - .heatmap-controls { - margin-bottom: 20px; - } - - .heatmap-legend { - display: flex; - align-items: center; - margin-bottom: 15px; - gap: 10px; - } - - .legend-gradient { - width: 200px; - height: 20px; - background: linear-gradient(to right, #f0f0f0, #fee, #fcc, #f99, #f66, #f33, #c00); - border: 1px solid #ddd; - border-radius: 3px; - } - - .legend-label { - font-size: 12px; - color: #666; - } - - .legend-max { - margin-left: 10px; - font-size: 12px; - color: #666; - } - - .heatmap-wrapper { - overflow-x: auto; - padding: 10px; - background: white; - border-radius: 5px; - box-shadow: 0 1px 3px rgba(0,0,0,0.1); - } - - #expense-heatmap { - min-width: 954px; - } \ No newline at end of file diff --git a/app/views/charts/show.html.haml b/app/views/charts/show.html.haml index c7cd9c3..ff8012a 100644 --- a/app/views/charts/show.html.haml +++ b/app/views/charts/show.html.haml @@ -51,4 +51,4 @@ 'heatmap-data-value': @heatmap_data.to_json } } - %svg#expense-heatmap{ width: '100%', height: '180', viewBox: '0 0 954 180' } \ No newline at end of file + %svg#expense-heatmap{ width: '100%', height: '180', viewBox: '0 0 954 180' } diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 70b9a00..f0fea8c 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -57,9 +57,6 @@ %li %a{ href: charts_path } Charts - %li - %a{ href: heatmap_charts_path } - Heatmap %li %a{ href: edit_user_path(current_user) } Account diff --git a/config/routes.rb b/config/routes.rb index db33494..9bef0e4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,11 +24,7 @@ post '/dashboard', to: 'dashboards#show' # Charts - resource :charts, only: [:show] do - member do - get 'heatmap' - end - end + resource :charts, only: [:show] # Authentication routes resource :session From 6ec62613d992a6e7916f7dd9600c5d073c37f9f0 Mon Sep 17 00:00:00 2001 From: Travis Dockter Date: Sun, 27 Jul 2025 18:19:04 -0600 Subject: [PATCH 3/3] Add rubocop changes --- Gemfile | 12 ++-- app/channels/application_cable/connection.rb | 6 +- app/controllers/categories_controller.rb | 8 +-- app/controllers/charts_controller.rb | 24 +++---- app/controllers/concerns/authentication.rb | 4 +- app/controllers/entries_controller.rb | 5 +- app/controllers/passwords_controller.rb | 24 ++++--- app/controllers/pwa_controller.rb | 14 ++-- app/controllers/recurrables_controller.rb | 5 +- app/controllers/sessions_controller.rb | 5 +- app/controllers/tags_controller.rb | 6 +- app/controllers/users_controller.rb | 13 ++-- app/models/category.rb | 2 +- app/models/concerns/taggable.rb | 4 +- app/models/entry.rb | 10 +-- app/models/user.rb | 6 +- app/services/demo_data_generator.rb | 14 ++-- config/routes.rb | 6 +- db/seeds.rb | 68 ++++++++++---------- 19 files changed, 107 insertions(+), 129 deletions(-) diff --git a/Gemfile b/Gemfile index fcb23d2..08dace4 100644 --- a/Gemfile +++ b/Gemfile @@ -5,14 +5,14 @@ ruby '3.4.4' gem 'puma' -gem 'rails', '~> 8.0' gem 'bootsnap', require: false gem 'importmap-rails' -gem 'turbo-rails' +gem 'rails', '~> 8.0' gem 'stimulus-rails' +gem 'turbo-rails' -gem 'solid_queue', '~> 1.1' gem 'mission_control-jobs' +gem 'solid_queue', '~> 1.1' gem 'propshaft' @@ -29,19 +29,19 @@ gem 'haml-rails' gem 'ransack' group :development, :test do + gem 'database_cleaner' gem 'debug', platforms: %i[mri mingw x64_mingw] gem 'rspec-rails' gem 'simplecov', require: false - gem 'database_cleaner' end group :development do - gem 'web-console' gem 'claude-on-rails' gem 'rubocop', require: false + gem 'rubocop-performance', require: false gem 'rubocop-rails', require: false gem 'rubocop-rspec', require: false - gem 'rubocop-performance', require: false + gem 'web-console' end group :production do diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb index 636eb43..228bf72 100644 --- a/app/channels/application_cable/connection.rb +++ b/app/channels/application_cable/connection.rb @@ -9,9 +9,9 @@ def connect private def set_current_user - if session = Session.find_by(id: cookies.signed[:session_id]) - self.current_user = session.user - end + return unless session = Session.find_by(id: cookies.signed[:session_id]) + + self.current_user = session.user end end end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 6ee56c0..679e0eb 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -8,8 +8,7 @@ def index end # GET /categories/1 or /categories/1.json - def show - end + def show; end # GET /categories/new def new @@ -17,8 +16,7 @@ def new end # GET /categories/1/edit - def edit - end + def edit; end # POST /categories or /categories.json def create @@ -88,7 +86,7 @@ def merge @old_category.destroy end redirect_to merge_categories_path, notice: 'Category was successfully merged.' - rescue ActiveRecord::RecordInvalid => e + rescue ActiveRecord::RecordInvalid redirect_to merge_categories_path, alert: 'There was an error. Category could not be merged.' end diff --git a/app/controllers/charts_controller.rb b/app/controllers/charts_controller.rb index 4dbe393..aabd58a 100644 --- a/app/controllers/charts_controller.rb +++ b/app/controllers/charts_controller.rb @@ -23,17 +23,11 @@ def show end end - respond_to do |format| - format.html - format.turbo_stream - end - end - private def calculate_monthly_profit_loss(year) - months = (1..12).map { |m| m.to_s } - data = months.map do |month| + months = (1..12).map(&:to_s) + months.map do |month| entries = current_user.entries .by_year(year) .by_month(month) @@ -50,14 +44,12 @@ def calculate_monthly_profit_loss(year) profit_loss: profit_loss } end - - data end def calculate_daily_expenses(year) start_date = Date.parse("#{year}-01-01") end_date = Date.parse("#{year}-12-31") - + # Get all expense entries for the year expense_entries = current_user.entries .by_year(year) @@ -65,7 +57,7 @@ def calculate_daily_expenses(year) .by_untracked(false) .group(:date) .select('date, COUNT(*) as count, SUM(amount) as total') - + # Convert to hash for easy lookup expenses_by_date = expense_entries.each_with_object({}) do |entry, hash| hash[entry.date.to_s] = { @@ -73,17 +65,17 @@ def calculate_daily_expenses(year) total: entry.total.to_f } end - + # Build complete year data with zeros for days without expenses daily_data = {} (start_date..end_date).each do |date| date_key = date.to_s daily_data[date_key] = expenses_by_date[date_key] || { count: 0, total: 0.0 } end - + # Calculate max expense for scaling - max_expense = daily_data.values.map { |d| d[:total] }.max || 0 - + max_expense = daily_data.values.map { |d| d[:total] }.max || 0 # rubocop:disable Rails/Pluck + { daily_expenses: daily_data, max_expense: max_expense, diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb index 50f8d74..dedc44d 100644 --- a/app/controllers/concerns/authentication.rb +++ b/app/controllers/concerns/authentication.rb @@ -7,8 +7,8 @@ module Authentication end class_methods do - def allow_unauthenticated_access(**options) - skip_before_action :require_authentication, **options + def allow_unauthenticated_access(**) + skip_before_action(:require_authentication, **) end end diff --git a/app/controllers/entries_controller.rb b/app/controllers/entries_controller.rb index 822eada..04c4ad8 100644 --- a/app/controllers/entries_controller.rb +++ b/app/controllers/entries_controller.rb @@ -15,8 +15,7 @@ def index end # GET /entries/1 or /entries/1.json - def show - end + def show; end # GET /entries/new def new @@ -84,7 +83,7 @@ def set_entry # Only allow a list of trusted parameters through. def entry_params params.require(:entry).permit(:date, :amount, :notes, :category_name, :income, :untracked, :user_id, - :category_id, tag_attributes: [:id, :name, :_destroy]) + :category_id, tag_attributes: %i[id name _destroy]) end def search_params diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 075fb7a..d06dd01 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -2,25 +2,23 @@ class PasswordsController < ApplicationController allow_unauthenticated_access before_action :set_user_by_token, only: %i[edit update] - def new - end + def new; end + + def edit; end def create - if user = User.find_by(email_address: params[:email_address]) - # In a real application without email, you might display this to the user or use SMS - # reset_url = edit_password_url(user.password_reset_token) - # Rails.logger.info "Password reset URL for #{user.email_address}: #{reset_url}" - flash[:notice] = 'Please contact an administrator to reset your password. ' - else - flash[:notice] = 'Please contact an administrator to reset your password.' - end + flash[:notice] = if User.find_by(email_address: params[:email_address]) + # In a real application without email, you might display this to the user or use SMS + # reset_url = edit_password_url(user.password_reset_token) + # Rails.logger.info "Password reset URL for #{user.email_address}: #{reset_url}" + 'Please contact an administrator to reset your password. ' + else + 'Please contact an administrator to reset your password.' + end redirect_to new_session_path end - def edit - end - def update if @user.update(params.permit(:password, :password_confirmation)) redirect_to new_session_path, notice: 'Password has been reset.' diff --git a/app/controllers/pwa_controller.rb b/app/controllers/pwa_controller.rb index ccd2312..239d29d 100644 --- a/app/controllers/pwa_controller.rb +++ b/app/controllers/pwa_controller.rb @@ -1,14 +1,14 @@ class PwaController < ApplicationController allow_unauthenticated_access - + def manifest - render json: render_to_string(template: "pwa/manifest", formats: :json), - content_type: "application/manifest+json" + render json: render_to_string(template: 'pwa/manifest', formats: :json), + content_type: 'application/manifest+json' end - + def service_worker - render file: Rails.public_path.join("service-worker.js"), - content_type: "application/javascript", + render file: Rails.public_path.join('service-worker.js'), + content_type: 'application/javascript', layout: false end -end \ No newline at end of file +end diff --git a/app/controllers/recurrables_controller.rb b/app/controllers/recurrables_controller.rb index ed38a5f..8c39d07 100644 --- a/app/controllers/recurrables_controller.rb +++ b/app/controllers/recurrables_controller.rb @@ -7,8 +7,7 @@ def index end # GET /recurrables/1 - def show - end + def show; end # GET /recurrables/new def new @@ -63,6 +62,6 @@ def set_recurrable # Only allow a list of trusted parameters through. def recurrable_params params.require(:recurrable).permit(:name, :day_of_month, :amount, :notes, :category_id, - tag_attributes: [:id, :name, :_destroy]) + tag_attributes: %i[id name _destroy]) end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 6b2107e..bb4c2f8 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,11 +1,10 @@ class SessionsController < ApplicationController allow_unauthenticated_access only: %i[new create] - rate_limit to: 10, within: 3.minutes, only: :create, with: -> { + rate_limit to: 10, within: 3.minutes, only: :create, with: lambda { redirect_to new_session_url, alert: 'Try again later.' } - def new - end + def new; end def create if user = User.authenticate_by(params.permit(:email_address, :password)) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 6bd21c3..8145615 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -7,8 +7,7 @@ def index end # GET /tags/1 - def show - end + def show; end # GET /tags/new def new @@ -16,8 +15,7 @@ def new end # GET /tags/1/edit - def edit - end + def edit; end # POST /tags def create diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 67b7e1f..b1238e3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,12 +1,14 @@ class UsersController < ApplicationController - allow_unauthenticated_access only: [:new, :create] - before_action :set_user, only: [:edit, :update] + allow_unauthenticated_access only: %i[new create] + before_action :set_user, only: %i[edit update] def new redirect_to root_path if authenticated? @user = User.new end + def edit; end + def create @user = User.new(user_params) @@ -18,9 +20,6 @@ def create end end - def edit - end - def update # Allow updating without providing current password if @user.update(user_update_params) @@ -43,9 +42,7 @@ def user_params def user_update_params # Only permit password fields if they are present permitted = [:email_address] - if params[:user][:password].present? - permitted += [:password, :password_confirmation] - end + permitted += %i[password password_confirmation] if params[:user][:password].present? params.require(:user).permit(permitted) end end diff --git a/app/models/category.rb b/app/models/category.rb index a2f38a1..e9db491 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,7 +1,7 @@ class Category < ApplicationRecord has_and_belongs_to_many :users - def self.ransackable_attributes(auth_object = nil) + def self.ransackable_attributes(_auth_object = nil) ['name'] end end diff --git a/app/models/concerns/taggable.rb b/app/models/concerns/taggable.rb index 0eb34cf..c51e510 100644 --- a/app/models/concerns/taggable.rb +++ b/app/models/concerns/taggable.rb @@ -13,12 +13,12 @@ def autosave_associated_records_for_tag self.tag = tag elsif tag.marked_for_destruction? self.tag = nil - self.save + save elsif tag.new_record? && Tag.find_by(name: tag.name).present? self.tag = Tag.find_by(name: tag.name) elsif tag.changed? && tag.name.blank? self.tag = nil - self.save + save elsif tag.changed? self.tag = Tag.find_or_create_by(name: tag.name) end diff --git a/app/models/entry.rb b/app/models/entry.rb index ef4dc4e..954ac4a 100644 --- a/app/models/entry.rb +++ b/app/models/entry.rb @@ -5,21 +5,21 @@ class Entry < ApplicationRecord belongs_to :category scope :by_year, ->(year) { where("strftime('%Y', date) = ?", year.to_s) if year.present? } - scope :by_month, ->(month) { + scope :by_month, lambda { |month| where("ltrim(strftime('%m', date), '0') = ?", month.to_s) unless month.blank? || month.to_i.zero? } scope :by_income, ->(income) { joins(:category).where(categories: { income: income }) if !!income == income } - scope :by_untracked, ->(untracked) { + scope :by_untracked, lambda { |untracked| joins(:category).where(categories: { untracked: untracked }) if !!untracked == untracked } scope :by_category_id, ->(category_id) { where(category_id: category_id) if category_id.present? } scope :by_tag_id, ->(tag_id) { where(tag_id: tag_id) if tag_id.present? } - def self.ransackable_attributes(auth_object = nil) - ['amount', 'date', 'notes'] + def self.ransackable_attributes(_auth_object = nil) + %w[amount date notes] end - def self.ransackable_associations(auth_object = nil) + def self.ransackable_associations(_auth_object = nil) ['category'] end diff --git a/app/models/user.rb b/app/models/user.rb index 64429c2..4a1d71d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -24,9 +24,9 @@ def tags end def remove_data - self.tags.destroy_all - self.entries.destroy_all - self.categories.destroy_all + tags.destroy_all + entries.destroy_all + categories.destroy_all end def password_reset_token diff --git a/app/services/demo_data_generator.rb b/app/services/demo_data_generator.rb index 16c6887..9b72f26 100644 --- a/app/services/demo_data_generator.rb +++ b/app/services/demo_data_generator.rb @@ -4,14 +4,14 @@ module DemoDataGenerator def random_amount(base, variance = 0.2) min = base * (1 - variance) max = base * (1 + variance) - (rand * (max - min) + min).round(2) + ((rand * (max - min)) + min).round(2) end def maybe_add_tag(tags, probability = 0.15) rand < probability ? tags.values.sample : nil end - def maybe_add_notes(category_name, amount = nil) + def maybe_add_notes(category_name, _amount = nil) category_notes = { 'Salary' => ['Monthly salary deposit', 'Regular paycheck', 'Direct deposit', 'Salary payment'], 'Freelance' => ['Project payment', 'Client invoice', 'Consulting work', 'Contract payment', 'Freelance gig'], @@ -29,12 +29,10 @@ def maybe_add_notes(category_name, amount = nil) } # 60% chance of having notes - if rand < 0.6 - notes_array = category_notes[category_name] || ['Payment', 'Purchase', 'Transaction'] - notes_array.sample - else - nil - end + return unless rand < 0.6 + + notes_array = category_notes[category_name] || %w[Payment Purchase Transaction] + notes_array.sample end def generate_daily_expenses(user, categories, tags, date) diff --git a/config/routes.rb b/config/routes.rb index 9bef0e4..413a604 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,7 @@ mount MissionControl::Jobs::Engine, at: '/jobs' get 'up' => 'rails/health#show', as: :rails_health_check - + # PWA routes get '/manifest.json', to: 'pwa#manifest' get '/service-worker.js', to: 'pwa#service_worker' @@ -33,10 +33,10 @@ get '/signup', to: 'users#new', as: :signup post '/signup', to: 'users#create' - resources :users, only: [:edit, :update] + resources :users, only: %i[edit update] # Root routes - constraints lambda { |req| Session.find_by(id: req.cookie_jar.signed[:session_id]).present? } do + constraints ->(req) { Session.find_by(id: req.cookie_jar.signed[:session_id]).present? } do root 'entries#new', as: :authenticated_root end diff --git a/db/seeds.rb b/db/seeds.rb index aefd028..8cabf57 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -173,17 +173,17 @@ # Holiday shopping in November/December if [11, 12].include?(month_start.month) (month_start..month_end).each do |date| - if rand < 0.15 # 15% chance each day - Entry.create!( - user: demo_user, - category: categories[:shopping], - date: date, - amount: random_amount(120, 0.6), - notes: 'Holiday shopping', - tag: tags[:gift] - ) - entry_count += 1 - end + next unless rand < 0.15 # 15% chance each day + + Entry.create!( + user: demo_user, + category: categories[:shopping], + date: date, + amount: random_amount(120, 0.6), + notes: 'Holiday shopping', + tag: tags[:gift] + ) + entry_count += 1 end end @@ -194,29 +194,29 @@ vacation_days.times do |day| vacation_date = vacation_start + day.days - if vacation_date <= month_end && vacation_date >= month_start - # Hotel - Entry.create!( - user: demo_user, - category: categories[:entertainment], - date: vacation_date, - amount: random_amount(150, 0.3), - notes: 'Hotel', - tag: tags[:vacation] - ) - entry_count += 1 - - # Dining out more - Entry.create!( - user: demo_user, - category: categories[:restaurants], - date: vacation_date, - amount: random_amount(80, 0.4), - notes: 'Vacation dining', - tag: tags[:vacation] - ) - entry_count += 1 - end + next unless vacation_date <= month_end && vacation_date >= month_start + + # Hotel + Entry.create!( + user: demo_user, + category: categories[:entertainment], + date: vacation_date, + amount: random_amount(150, 0.3), + notes: 'Hotel', + tag: tags[:vacation] + ) + entry_count += 1 + + # Dining out more + Entry.create!( + user: demo_user, + category: categories[:restaurants], + date: vacation_date, + amount: random_amount(80, 0.4), + notes: 'Vacation dining', + tag: tags[:vacation] + ) + entry_count += 1 end end