diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index fd0c33f6e..6d0af6939 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -108,7 +108,7 @@ class UsersController < ApplicationController
def user_params
params.require(:user).permit(
:first_name, :last_name, :email, :profile_image, :redirect_to, :delete_profile_image, :onboarded_at,
- :show_sidebar, :default_period, :default_account_order, :show_ai_sidebar, :ai_enabled, :theme, :set_onboarding_preferences_at, :set_onboarding_goals_at, :locale,
+ :show_sidebar, :default_period, :default_account_order, :show_ai_sidebar, :ai_enabled, :theme, :set_onboarding_preferences_at, :set_onboarding_goals_at, :locale, :rule_prompts_enabled,
family_attributes: [ :name, :currency, :country, :date_format, :timezone, :locale, :month_start_day, :moniker, :id ],
goals: []
)
diff --git a/app/models/user.rb b/app/models/user.rb
index 4cb17c6bd..f985f63f8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -311,6 +311,15 @@ class User < ApplicationRecord
end
end
+ # Virtual attribute for UI: inverts rule_prompts_disabled for a more intuitive toggle
+ def rule_prompts_enabled
+ !rule_prompts_disabled
+ end
+
+ def rule_prompts_enabled=(value)
+ self.rule_prompts_disabled = !ActiveModel::Type::Boolean.new.cast(value)
+ end
+
# Transactions preferences management
def transactions_section_collapsed?(section_key)
preferences&.dig("transactions_collapsed_sections", section_key) == true
diff --git a/app/views/settings/preferences/show.html.erb b/app/views/settings/preferences/show.html.erb
index eee21b87e..ef7e51e2e 100644
--- a/app/views/settings/preferences/show.html.erb
+++ b/app/views/settings/preferences/show.html.erb
@@ -56,3 +56,17 @@
<% end %>
<% end %>
+
+<%= settings_section title: t(".automation_title"), subtitle: t(".automation_subtitle") do %>
+
+
+
<%= t(".rule_prompts_label") %>
+
<%= t(".rule_prompts_hint") %>
+
+
+ <%= styled_form_with model: @user, data: { controller: "auto-submit-form" } do |form| %>
+ <%= form.hidden_field :redirect_to, value: "preferences" %>
+ <%= form.toggle :rule_prompts_enabled, data: { auto_submit_form_target: "auto" } %>
+ <% end %>
+
+<% end %>
diff --git a/config/locales/views/settings/en.yml b/config/locales/views/settings/en.yml
index d66cb7882..0f027a4fb 100644
--- a/config/locales/views/settings/en.yml
+++ b/config/locales/views/settings/en.yml
@@ -54,6 +54,10 @@ en:
month_start_day: Budget month starts on
month_start_day_hint: Set when your budget month starts (e.g., payday)
month_start_day_warning: Your budgets and MTD calculations will use this custom start day instead of the 1st of each month.
+ automation_title: Automation
+ automation_subtitle: Control automatic behavior
+ rule_prompts_label: Auto-suggest rules when categorizing
+ rule_prompts_hint: Show a prompt to create a rule when you assign a category to a transaction
profiles:
destroy:
cannot_remove_self: You cannot remove yourself from the account.
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
index 46aa0637f..496d825f9 100644
--- a/test/models/user_test.rb
+++ b/test/models/user_test.rb
@@ -501,4 +501,28 @@ class UserTest < ActiveSupport::TestCase
assert_not Family.exists?(family.id)
assert_not ActiveStorage::Attachment.exists?(export_attachment_id)
end
+
+ test "rule_prompts_enabled returns inverse of rule_prompts_disabled" do
+ @user.rule_prompts_disabled = false
+ assert @user.rule_prompts_enabled
+
+ @user.rule_prompts_disabled = true
+ assert_not @user.rule_prompts_enabled
+ end
+
+ test "setting rule_prompts_enabled updates rule_prompts_disabled" do
+ @user.rule_prompts_enabled = true
+ assert_not @user.rule_prompts_disabled
+
+ @user.rule_prompts_enabled = false
+ assert @user.rule_prompts_disabled
+ end
+
+ test "rule_prompts_enabled= coerces string values correctly" do
+ @user.rule_prompts_enabled = "1"
+ assert_not @user.rule_prompts_disabled
+
+ @user.rule_prompts_enabled = "0"
+ assert @user.rule_prompts_disabled
+ end
end