From c62002381b18e1cb3783857eecab5885b448f83d Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Thu, 10 Aug 2017 11:30:57 +0200 Subject: [PATCH] Add default settings migration and concern --- app/controllers/application_controller.rb | 2 +- .../account/preferences_controller.rb | 2 +- app/models/concerns/settings_model.rb | 22 ++++++++ app/models/user.rb | 15 ++++- app/serializers/jsonb_hash_serializer.rb | 11 ++++ .../account/preferences/index.html.erb | 8 +-- .../20170809131000_refactor_user_settings.rb | 53 ++++++++++++++++++ scinote-web-v1.0.0.tgz | Bin 0 -> 23258 bytes spec/models/user_spec.rb | 9 +-- 9 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 app/models/concerns/settings_model.rb create mode 100644 app/serializers/jsonb_hash_serializer.rb create mode 100644 db/migrate/20170809131000_refactor_user_settings.rb create mode 100644 scinote-web-v1.0.0.tgz diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e0e50c25b..678f4b7aa 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -87,6 +87,6 @@ class ApplicationController < ActionController::Base end def set_time_zone(&block) - Time.use_zone(current_user.time_zone, &block) + Time.use_zone(current_user.settings[:time_zone], &block) end end diff --git a/app/controllers/users/settings/account/preferences_controller.rb b/app/controllers/users/settings/account/preferences_controller.rb index ac85f0148..b096bfa1b 100644 --- a/app/controllers/users/settings/account/preferences_controller.rb +++ b/app/controllers/users/settings/account/preferences_controller.rb @@ -115,7 +115,7 @@ module Users def update_params params.require(:user).permit( - :time_zone + settings: :time_zone ) end end diff --git a/app/models/concerns/settings_model.rb b/app/models/concerns/settings_model.rb new file mode 100644 index 000000000..c74425422 --- /dev/null +++ b/app/models/concerns/settings_model.rb @@ -0,0 +1,22 @@ +module SettingsModel + extend ActiveSupport::Concern + + @@default_settings = HashWithIndifferentAccess.new + + included do + serialize :settings, JsonbHashSerializer + after_initialize :init_default_settings, if: :new_record? + end + + class_methods do + def default_settings(dfs) + @@default_settings.merge!(dfs) + end + end + + protected + + def init_default_settings + self.settings = @@default_settings + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c7c5fb3dd..bceb665a2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,6 @@ class User < ApplicationRecord include SearchableModel + include SettingsModel acts_as_token_authenticatable devise :invitable, :confirmable, :database_authenticatable, :registerable, @@ -33,9 +34,19 @@ class User < ApplicationRecord validates_attachment :avatar, :content_type => { :content_type => ["image/jpeg", "image/png"] }, size: { less_than: Constants::AVATAR_MAX_SIZE_MB.megabytes } - validates :time_zone, presence: true validate :time_zone_check + default_settings( + time_zone: 'UTC', + notifications: { + assignments: true, + assignments_email: false, + recent: true, + recent_email: false, + system_message_email: false + } + ) + # Relations has_many :user_teams, inverse_of: :user has_many :teams, through: :user_teams @@ -384,7 +395,7 @@ class User < ApplicationRecord end def time_zone_check - if time_zone.nil? or ActiveSupport::TimeZone.new(time_zone).nil? + if settings[:time_zone].nil? or ActiveSupport::TimeZone.new(settings[:time_zone]).nil? errors.add(:time_zone) end end diff --git a/app/serializers/jsonb_hash_serializer.rb b/app/serializers/jsonb_hash_serializer.rb new file mode 100644 index 000000000..f01f29560 --- /dev/null +++ b/app/serializers/jsonb_hash_serializer.rb @@ -0,0 +1,11 @@ +class JsonbHashSerializer + def self.dump(hash) + hash.to_json + end + + def self.load(hash) + hash ||= {} + hash = JSON.parse(hash) if hash.instance_of? String + hash.with_indifferent_access + end +end diff --git a/app/views/users/settings/account/preferences/index.html.erb b/app/views/users/settings/account/preferences/index.html.erb index 18ed8eeae..0f06e94ce 100644 --- a/app/views/users/settings/account/preferences/index.html.erb +++ b/app/views/users/settings/account/preferences/index.html.erb @@ -12,7 +12,7 @@ <%= form_for(@user, url: update_preferences_path(format: :json), remote: true, - html: { method: :put, 'data-for' => 'time_zone' }) do |f| %> + html: { method: :put, 'data-for' => 'settings[time_zone]' }) do |f| %>
<%= f.label t("users.settings.account.preferences.edit.time_zone_label") %> @@ -21,9 +21,9 @@ disabled="disabled" autocomplete="off" type="text" - value="<%= @user.time_zone %>" - name="fake_user[time_zone]" - id="fake_user_time_zone"> + value="<%= @user.settings[:time_zone] %>" + name="fake_user[settings][time_zone]" + id="fake_user_settings_time_zone"> <%=t "general.edit" %> diff --git a/db/migrate/20170809131000_refactor_user_settings.rb b/db/migrate/20170809131000_refactor_user_settings.rb new file mode 100644 index 000000000..4dd54cf8d --- /dev/null +++ b/db/migrate/20170809131000_refactor_user_settings.rb @@ -0,0 +1,53 @@ +class RefactorUserSettings < ActiveRecord::Migration[5.1] + def up + add_column :users, :settings, :jsonb, default: {}, null: false + + User.find_each do |user| + settings = { + time_zone: user['time_zone'], + notifications: { + assignments: user['assignments_notification'], + assignments_email: user['assignments_notification_email'], + recent: user['recent_notification'], + recent_email: user['recent_notification_email'], + system_message_email: user['system_message_notification_email'] + } + } + user.update(settings: settings) + end + + remove_column :users, :time_zone, :string + remove_column :users, :assignments_notification, :boolean + remove_column :users, :assignments_notification_email, :boolean + remove_column :users, :recent_notification, :boolean + remove_column :users, :recent_notification_email, :boolean + remove_column :users, :system_message_notification_email, :boolean + end + + def down + add_column :users, :time_zone, :string, default: false + add_column :users, :assignments_notification, :boolean, default: false + add_column :users, :assignments_notification_email, :boolean, default: false + add_column :users, :recent_notification, :boolean, default: false + add_column :users, :recent_notification_email, :boolean, default: false + add_column :users, + :system_message_notification_email, :boolean, default: false + + User.find_each do |user| + user.time_zone = user.settings[:time_zone] + user.assignments_notification = + user.settings[:notifications][:assignments] + user.assignments_notification_email = + user.settings[:notifications][:assignments_email] + user.recent_notification = + user.settings[:notifications][:recent] + user.recent_notification_email = + user.settings[:notifications][:recent_email] + user.system_message_notification_email = + user.settings[:notifications][:system_message_email] + user.save + end + + remove_column :users, :settings, :jsonb + end +end diff --git a/scinote-web-v1.0.0.tgz b/scinote-web-v1.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..289870cc3256cd95766a2e77eddad30c733a856d GIT binary patch literal 23258 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

sCves%HyF`-(k`7CVG6B0cS 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 U^JzZK=RQCGKU)njX8>RV0NuAJ$^ZZW literal 0 HcmV?d00001 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index aa55b0a06..b4c1515d7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -28,7 +28,6 @@ describe User, type: :model do it { should have_db_column :confirmed_at } it { should have_db_column :confirmation_sent_at } it { should have_db_column :unconfirmed_email } - it { should have_db_column :time_zone } it { should have_db_column :invitation_token } it { should have_db_column :invitation_created_at } it { should have_db_column :invitation_sent_at } @@ -38,12 +37,8 @@ describe User, type: :model do it { should have_db_column :invited_by_type } it { should have_db_column :invitations_count } it { should have_db_column :tutorial_status } - it { should have_db_column :assignments_notification } - it { should have_db_column :recent_notification } - it { should have_db_column :assignments_notification_email } - it { should have_db_column :recent_notification_email } + it { should have_db_column :settings } it { should have_db_column :current_team_id } - it { should have_db_column :system_message_notification_email } it { should have_db_column :authentication_token } end @@ -115,7 +110,7 @@ describe User, type: :model do it { should validate_presence_of :full_name } it { should validate_presence_of :initials } it { should validate_presence_of :email } - it { should validate_presence_of :time_zone } + it { should validate_presence_of :settings } it do should validate_length_of(:full_name).is_at_most(