Skip to content

Commit 00b5f47

Browse files
committed
Merge branch '0valt/seeds' into temporary-branch-for-testing-ci-failures
2 parents 54243ab + 70499f5 commit 00b5f47

File tree

7 files changed

+123
-24
lines changed

7 files changed

+123
-24
lines changed

app/controllers/post_types_controller.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ def post_type_params
5555
end
5656

5757
def clear_cache!
58+
# FIXME: this is likely not clearing cache for rep changes
5859
Rails.cache.delete 'network/post_types/rep_changes'
59-
Rails.cache.delete 'network/post_types/post_type_ids'
60+
PostType.clear_ids_cache
6061
current_community = RequestContext.community
6162
Community.all.each do |c|
6263
RequestContext.community = c

app/helpers/seeds_helper.rb

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
11
module SeedsHelper
2-
def update_from_seeds(type, unique_key, value_attribute)
3-
data = YAML.load_file(Rails.root.join("db/seeds/#{type}.yml"))
4-
cls = type.to_s.singularize.classify.constantize
5-
data.each do |seed|
6-
cls.unscoped.where(unique_key => seed[unique_key.to_s]).update(value_attribute => seed[value_attribute.to_s])
2+
# Gets the list of seed file paths
3+
# @param seed_name [String, nil] optional specific seed name to run
4+
# @return [Array<String>]
5+
def self.files(seed_name)
6+
find_glob = if seed_name.present?
7+
"db/seeds/**/#{seed_name.underscore}.yml"
8+
else
9+
'db/seeds/**/*.yml'
10+
end
11+
12+
# Get all seed files and determine their model types
13+
Dir.glob(Rails.root.join(find_glob))
14+
end
15+
16+
# Parses model classes from the list of file paths
17+
# @param files [Array<String>] list of seed file paths
18+
# @return [Array<Class>]
19+
def self.types(files)
20+
files.map do |f|
21+
basename = Pathname.new(f).relative_path_from(Pathname.new(Rails.root.join('db/seeds'))).to_s
22+
basename.gsub('.yml', '').singularize.classify.constantize
723
end
824
end
25+
26+
# Prioritizes models such that dependent ones are created after the specified ones
27+
# @param types [Array<Class>] list of model classes
28+
# @param files [Array<String>] list of seed file paths
29+
# @return [Hash<String, Class>]
30+
def self.prioritize(types, files)
31+
priority = [PostType, CloseReason, License, TagSet, PostHistoryType, User, Ability, CommunityUser, Filter]
32+
33+
files.zip(types).to_h.sort do |a, b|
34+
(priority.index(a.second) || 999) <=> (priority.index(b.second) || 999)
35+
end.to_h
36+
end
937
end

app/models/post_type.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def system?
2424
['HelpDoc', 'PolicyDoc'].include?(name)
2525
end
2626

27+
def self.clear_ids_cache
28+
Rails.cache.delete 'network/post_types/post_type_ids', include_community: false
29+
end
30+
2731
def self.mapping
2832
Rails.cache.fetch 'network/post_types/post_type_ids', include_community: false do
2933
PostType.all.to_h { |pt| [pt.name, pt.id] }

db/seeds.rb

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,9 @@
22

33
Rails.application.eager_load!
44

5-
if ENV['SEEDS'].present?
6-
find_glob = "db/seeds/**/#{ENV['SEEDS'].underscore}.yml"
7-
else
8-
find_glob = 'db/seeds/**/*.yml'
9-
end
10-
11-
# Get all seed files and determine their model types
12-
files = Dir.glob(Rails.root.join(find_glob))
13-
types = files.map do |f|
14-
basename = Pathname.new(f).relative_path_from(Pathname.new(Rails.root.join('db/seeds'))).to_s
15-
basename.gsub('.yml', '').singularize.classify.constantize
16-
end
17-
18-
# Prioritize the following models (in this order) such that models depending on them get created after
19-
priority = [PostType, CloseReason, License, TagSet, PostHistoryType, User, Ability, CommunityUser, Filter]
20-
sorted = files.zip(types).to_h.sort do |a, b|
21-
(priority.index(a.second) || 999) <=> (priority.index(b.second) || 999)
22-
end.to_h
5+
files = SeedsHelper.files(ENV['SEEDS'])
6+
types = SeedsHelper.types(files)
7+
sorted = SeedsHelper.prioritize(types, files)
238

249
def expand_communities(type, seed)
2510
if type.column_names.include?('community_id') && !seed.include?('community_id')
@@ -61,6 +46,12 @@ def create_objects(type, seed)
6146
skipped = objs.select { |o| o.errors.any? }.size
6247
created = objs.select { |o| !o.errors.any? }.size
6348

49+
# Post type cache must be manually cleared \
50+
# (its mappings need it, but only the controller clears the cache on create)
51+
if type == PostType
52+
type.clear_ids_cache
53+
end
54+
6455
[created, skipped]
6556
end
6657

test/.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ inherit_from:
44
Layout/LineLength:
55
Max: 150
66

7+
Metrics/BlockLength:
8+
CountAsOne: ['array']
9+
710
Metrics/ClassLength:
811
Enabled: false

test/helpers/seeds_helper_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
require 'test_helper'
2+
3+
class SeedsHelperTest < ActionView::TestCase
4+
test 'calling SeedsHelper#files with seed_name should constrain paths' do
5+
files = SeedsHelper.files('posts')
6+
7+
assert_instance_of Array, files
8+
assert_equal files.length, 1
9+
assert_includes files, "#{Dir.pwd}/db/seeds/posts.yml"
10+
end
11+
end

test/test_helper.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,67 @@
1010
require 'minitest/ci'
1111
Minitest::Ci.report_dir = Rails.root.join('test/reports/minitest').to_s
1212

13+
# cleanup seeds after all tests are run (can't use teardown callbacks as they run after each test)
14+
Minitest.after_run do
15+
# IMPORTANT: the order is very specific to prevent FK constraint errors without disabling them
16+
models = [
17+
WarningTemplate,
18+
ModWarning,
19+
ThreadFollower,
20+
Comment,
21+
CommentThread,
22+
Reaction,
23+
ReactionType,
24+
Flag,
25+
PinnedLink,
26+
PostFlagType,
27+
SuggestedEdit,
28+
Vote,
29+
Post,
30+
PostHistory,
31+
PostHistoryTag,
32+
PostHistoryType,
33+
UserAbility,
34+
AbilityQueue,
35+
Ability,
36+
CategoryFilterDefault,
37+
Category,
38+
CloseReason,
39+
PostType,
40+
License,
41+
TagSynonym,
42+
Tag,
43+
TagSet,
44+
Filter,
45+
CommunityUser,
46+
UserWebsite,
47+
AuditLog,
48+
BlockedItem,
49+
EmailLog,
50+
ErrorLog,
51+
Subscription,
52+
User,
53+
Notification,
54+
SiteSetting,
55+
Community
56+
]
57+
58+
models.each do |model|
59+
if model == PostType
60+
model.unscoped.where.not(answer_type_id: nil).delete_all
61+
model.unscoped.where(answer_type_id: nil).delete_all
62+
elsif model == Tag
63+
model.unscoped.where.not(parent_id: nil).delete_all
64+
model.unscoped.where(parent_id: nil).delete_all
65+
elsif model == User
66+
model.unscoped.where.not(deleted_by_id: nil).delete_all
67+
model.unscoped.where(deleted_by_id: nil).delete_all
68+
else
69+
model.unscoped.all.delete_all
70+
end
71+
end
72+
end
73+
1374
Dir.glob(Rails.root.join('test/support/**/*.rb')).sort.each { |f| require f }
1475

1576
class ActiveSupport::TestCase

0 commit comments

Comments
 (0)