diff --git a/app/models/community_user.rb b/app/models/community_user.rb index a62926dcc..b1390fcf8 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -14,6 +14,10 @@ class CommunityUser < ApplicationRecord after_create :prevent_ulysses_case + def system? + user_id == -1 + end + def suspended? return true if is_suspended && !suspension_end.past? diff --git a/db/seeds.rb b/db/seeds.rb index 9c38c693d..11cb350a0 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -16,11 +16,75 @@ end # Prioritize the following models (in this order) such that models depending on them get created after -priority = [PostType, CloseReason, License, TagSet, PostHistoryType, User, Filter] +priority = [PostType, CloseReason, License, TagSet, PostHistoryType, User, Ability, CommunityUser, Filter] sorted = files.zip(types).to_h.sort do |a, b| (priority.index(a.second) || 999) <=> (priority.index(b.second) || 999) end.to_h +def expand_communities(type, seed) + if type.column_names.include?('community_id') && !seed.include?('community_id') + # if model includes a community_id, create the seed for every community + Community.all.map { |c| seed.deep_symbolize_keys.merge(community_id: c.id) } + else + # otherwise, no need to worry, just create it + [seed] + end +end + +def expand_ids(type, seeds) + # Transform all _id relations into the actual rails objects to pass validations + seeds.map do |seed| + columns = type.column_names.select { |name| name.match(/^.*_id$/) } + new_seed = seed.deep_symbolize_keys + columns.each do |column| + begin + column_type_name = column.chomp('_id') + column_type = column_type_name.classify.constantize + new_seed = new_seed.except(column.to_sym) + .merge(column_type_name.to_sym => column_type.unscoped.find(seed[column.to_sym])) + rescue StandardError + # Either the type does not exist or the value specified as the id is not valid, ignore. + next + end + end + new_seed + end +end + +def create_objects(type, seed) + seeds = expand_communities(type, seed) + seeds = expand_ids(type, seeds) + + # Actually create the objects and count successes + objs = type.create seeds + + skipped = objs.select { |o| o.errors.any? }.size + created = objs.select { |o| !o.errors.any? }.size + + [created, skipped] +end + +def ensure_system_user_abilities + system_users = CommunityUser.unscoped.where(user_id: -1) + + system_users.each do |su| + abilities = Ability.unscoped + .where(internal_id: ['everyone', 'mod', 'unrestricted']) + .where(community_id: su.community_id) + + user_abilities = UserAbility.unscoped.where(community_user_id: su.id) + + abilities.each do |ab| + unless user_abilities.any? { |ua| ua.ability_id == ab.id } + UserAbility.create community_user_id: su.id, ability: ab + end + rescue => e + puts "#{type}: failed to add \"#{ab.name}\" to system user \"#{su.id}\" on \"#{su.community.name}\"" + puts e + end + end +end + sorted.each do |f, type| begin processed = ERB.new(File.read(f)).result(binding) @@ -83,40 +147,17 @@ end end else - seeds = if type.column_names.include?('community_id') && !seed.include?('community_id') - # if model includes a community_id, create the seed for every community - Community.all.map { |c| seed.deep_symbolize_keys.merge(community_id: c.id) } - else - # otherwise, no need to worry, just create it - [seed] - end - - # Transform all _id relations into the actual rails objects to pass validations - seeds = seeds.map do |seed| - columns = type.column_names.select { |name| name.match(/^.*_id$/) } - new_seed = seed.deep_symbolize_keys - columns.each do |column| - begin - column_type_name = column.chomp('_id') - column_type = column_type_name.classify.constantize - new_seed = new_seed.except(column.to_sym) - .merge(column_type_name.to_sym => column_type.unscoped.find(seed[column.to_sym])) - rescue StandardError - # Either the type does not exist or the value specified as the id is not valid, ignore. - next - end - end - new_seed - end + new_created, new_skipped = create_objects(type, seed) + created += new_created + skipped += new_skipped - # Actually create the objects and count successes - objs = type.create seeds - skipped += objs.select { |o| o.errors.any? }.size - created += objs.select { |o| !o.errors.any? }.size + if type == CommunityUser + ensure_system_user_abilities + end end end unless Rails.env.test? - puts "#{type}: Errored #{errored}, Created #{created}, #{updated > 0 ? "updated #{updated}, " : ''}skipped #{skipped}" + puts "#{type}: errored #{errored}, created #{created}, #{updated > 0 ? "updated #{updated}, " : ''}skipped #{skipped}" end rescue StandardError => e puts "Got error #{e}. Continuing..." diff --git a/db/seeds/community_users.yml b/db/seeds/community_users.yml new file mode 100644 index 000000000..4935d657d --- /dev/null +++ b/db/seeds/community_users.yml @@ -0,0 +1,7 @@ +- deleted: false + is_admin: true + is_moderator: true + is_suspended: false + post_count: 0 + reputation: 1 + user_id: -1 \ No newline at end of file