Class: Thredded::DatabaseSeeder

Inherits:
Object
  • Object
show all
Includes:
ApplicationHelper, LogTime
Defined in:
lib/thredded/database_seeder.rb

Overview

rubocop:disable Metrics/MethodLength

Defined Under Namespace

Modules: LogTime Classes: BaseSeedData, CollectionSeedData, FirstMessageboard, FirstSeedData, FirstUser, Posts, PrivatePosts, PrivateTopics, Topics, Users

Constant Summary collapse

SKIP_CALLBACKS =
[
  [Thredded::Post, :commit, :after, :update_parent_last_user_and_time_from_last_post, on: %i[create destroy]],
  [Thredded::Post, :commit, :after, :update_parent_last_user_and_time_from_last_post_if_moderation_state_changed,
   on: :update],
  [Thredded::Post, :commit, :after, :auto_follow_and_notify, on: %i[create update]],
  [Thredded::PrivatePost, :commit, :after, :update_parent_last_user_and_timestamp, on: %i[create destroy]],
  [Thredded::PrivatePost, :commit, :after, :notify_users, on: [:create]],
].freeze
DISABLE_COUNTER_CACHE =
[Thredded::Post, Thredded::PrivatePost].freeze
WRITEABLE_READONLY_ATTRIBUTES =
[
  [Thredded::Topic, 'posts_count'],
  [Thredded::PrivateTopic, 'posts_count'],
].freeze

Constants included from NavHelper

NavHelper::USER_NAV_MODERATION_PAGES, NavHelper::USER_NAV_PREFERENCES_PAGES, NavHelper::USER_NAV_PRIVATE_TOPICS_PAGES, NavHelper::USER_NAV_UNREAD_TOPICS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ApplicationHelper

#global_nav_icons_count, #paginate, #posts_pending_moderation_count, #render_posts, #thredded_container_classes, #thredded_container_data, #thredded_page, #time_ago, #topic_css_classes, #topic_follow_reason_text, #user_link, #user_mention, #view_hooks

Methods included from IconHelper

#define_svg_icons, #inline_svg_once, #shared_inline_svg

Methods included from RenderHelper

#render_collection_to_strings_with_cache

Methods included from NavHelper

#current_page_moderation?, #current_page_preferences?, #current_page_private_topics?, #current_page_unread_topics?, #nav_back_path

Methods included from UrlsHelper

#delete_post_path, #edit_post_path, #edit_preferences_path, #edit_preferences_url, #mark_unread_path, #permalink_path, #post_path, #post_url, #quote_post_path, #search_path, #send_private_message_path, #topic_path, #topic_url, #unread_topics_path, #user_path

Methods included from LogTime

included, #log_time, #print_time_diff

Class Method Details

.delete_callbacks(klass, name, *filter_list, &block) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/thredded/database_seeder.rb', line 102

def self.delete_callbacks(klass, name, *filter_list, &block)
  type, filters, _options = klass.normalize_callback_params(filter_list, block)
  klass.__update_callbacks(name) do |target, chain|
    filters.each do |filter|
      chain.delete(chain.find { |c| c.matches?(type, filter) })
    end
    target.send :set_callbacks, name, chain
  end
end

.run(**kwargs) ⇒ Object



112
113
114
# File 'lib/thredded/database_seeder.rb', line 112

def self.run(**kwargs)
  new.run(**kwargs)
end

.with_seeder_tweaksObject

Applies global tweaks required to run seeder methods for the given block.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/thredded/database_seeder.rb', line 61

def self.with_seeder_tweaks
  # Disable callbacks to avoid creating notifications and performing unnecessary updates
  DISABLE_COUNTER_CACHE.each do |klass|
    if Thredded::Compat.rails_gte_72?
      klass.class_eval do
        class_attribute :original_counter_cached_association_names
        self.original_counter_cached_association_names = counter_cached_association_names
        self.counter_cached_association_names = []
      end
    else
      klass.send(:alias_method, :original_each_counter_cached_associations, :each_counter_cached_associations)
      klass.send(:define_method, :each_counter_cached_associations) {}
    end
  end
  SKIP_CALLBACKS.each { |(klass, *args)| delete_callbacks(klass, *args) }
  WRITEABLE_READONLY_ATTRIBUTES.each { |(klass, attr)| klass.readonly_attributes.delete(attr) }
  logger_was = ActiveRecord::Base.logger
  ActiveRecord::Base.logger = nil
  yield
ensure
  # Re-enable callbacks and counter cache
  DISABLE_COUNTER_CACHE.each do |klass|
    if Thredded::Compat.rails_gte_72?
      klass.class_eval do
        self.counter_cached_association_names = original_counter_cached_association_names
      end
    else
      klass.send(:remove_method, :each_counter_cached_associations)
      klass.send(:alias_method, :each_counter_cached_associations, :original_each_counter_cached_associations)
      klass.send(:remove_method, :original_each_counter_cached_associations)
    end
  end
  SKIP_CALLBACKS.each do |(klass, *args)|
    args = args.dup
    klass.send(:set_options_for_callbacks!, args)
    klass.set_callback(*args)
  end
  WRITEABLE_READONLY_ATTRIBUTES.each { |(klass, attr)| klass.readonly_attributes << attr }
  ActiveRecord::Base.logger = logger_was
end

Instance Method Details

#create_additional_messageboardsObject



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/thredded/database_seeder.rb', line 175

def create_additional_messageboards
  meta_group_id = MessageboardGroup.create!(name: 'Meta').id
  additional_messageboards = [
    ['Off-Topic', "Talk about whatever here, it's all good."],
    ['Help, Bugs, and Suggestions',
     'Need help using the forum? Want to report a bug or make a suggestion? This is the place.', meta_group_id],
    ['Praise', 'Want to tell us how great we are? This is the place.', meta_group_id]
  ]
  log "Creating #{additional_messageboards.length} additional messageboards...\n"
  additional_messageboards.each do |(name, description, group_id)|
    messageboard = Messageboard.create!(name: name, description: description, messageboard_group_id: group_id)
    topics = Topics.new(self).create(count: rand(1..3), messageboard: messageboard)
    Posts.new(self).create(count: (1..2), topics: topics)
  end
end

#fake_post_contentsObject



149
150
151
# File 'lib/thredded/database_seeder.rb', line 149

def fake_post_contents
  with_mentions(@fake_post_contents ? @fake_post_contents.sample : FakeContent.post_content)
end

#first_messageboardObject



171
172
173
# File 'lib/thredded/database_seeder.rb', line 171

def first_messageboard
  @first_messageboard ||= FirstMessageboard.new(self).find_or_create
end

#first_userObject



159
160
161
# File 'lib/thredded/database_seeder.rb', line 159

def first_user
  @first_user ||= FirstUser.new(self).find_or_create
end

#follow_some_topics_by_user(user, count: (1..10)) ⇒ Object



228
229
230
231
232
# File 'lib/thredded/database_seeder.rb', line 228

def follow_some_topics_by_user(user, count: (1..10))
  topics.sample(count.min + rand(count.max - count.min + 2)).each do |topic|
    Thredded::UserTopicFollow.create_with(reason: :manual).find_or_create_by(user_id: user.id, topic_id: topic.id)
  end
end

#log(message) ⇒ Object



139
140
141
142
# File 'lib/thredded/database_seeder.rb', line 139

def log(message)
  STDERR.write "- #{message}"
  STDERR.flush
end

#posts(count: (1..1)) ⇒ Object



207
208
209
# File 'lib/thredded/database_seeder.rb', line 207

def posts(count: (1..1))
  @posts ||= Posts.new(self).find_or_create(count: count)
end

#private_posts(count: (1..1)) ⇒ Object



211
212
213
# File 'lib/thredded/database_seeder.rb', line 211

def private_posts(count: (1..1))
  @private_posts ||= PrivatePosts.new(self).find_or_create(count: count)
end

#private_topics(count: 1) ⇒ Object



203
204
205
# File 'lib/thredded/database_seeder.rb', line 203

def private_topics(count: 1)
  @private_topics ||= PrivateTopics.new(self).find_or_create(count: count)
end

#read_some_topics_by_user(user, count: (1..10)) ⇒ Object



245
246
247
248
249
# File 'lib/thredded/database_seeder.rb', line 245

def read_some_topics_by_user(user, count: (1..10))
  topics.sample(count.min + rand(count.max - count.min + 2)).each do |topic|
    read_topic(topic, user.id)
  end
end

#read_topic(topic, user_id) ⇒ Object



251
252
253
254
255
256
257
258
259
# File 'lib/thredded/database_seeder.rb', line 251

def read_topic(topic, user_id)
  last_read_post =
    if rand(2).zero?
      topic.posts.order_newest_first.first(2).last
    else
      topic.posts.order_newest_first.first
    end
  Thredded::UserTopicReadState.touch!(user_id, last_read_post)
end

#run(users: 200, topics: 70, posts: (1..70)) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/thredded/database_seeder.rb', line 116

def run(users: 200, topics: 70, posts: (1..70))
  log "Seeding the database...\n"
  self.class.with_seeder_tweaks do
    t_txn_0 = nil
    Messageboard.transaction do
      initialize_fake_post_contents(topics: topics, posts: posts)
      users(count: users)
      first_messageboard
      topics(count: topics)
      private_topics(count: topics)
      posts(count: posts)
      private_posts(count: posts)
      create_additional_messageboards
      follow_some_topics
      read_some_topics(count: (topics / 4..topics / 3))
      update_messageboards_data
      t_txn_0 = Time.now.to_f
      log 'Committing transaction and running after_commit callbacks'
    end
    print_time_diff t_txn_0
  end
end

#topics(count: 1) ⇒ Object



199
200
201
# File 'lib/thredded/database_seeder.rb', line 199

def topics(count: 1)
  @topics ||= Topics.new(self).find_or_create(count: count)
end

#user_detailsObject



167
168
169
# File 'lib/thredded/database_seeder.rb', line 167

def user_details
  @user_details ||= users.index_with(&:thredded_user_detail)
end

#users(count: 1) ⇒ Object



163
164
165
# File 'lib/thredded/database_seeder.rb', line 163

def users(count: 1)
  @users ||= Users.new(self).find_or_create(count: count)
end

#with_mentions(post, mentions_count: rand(3)) ⇒ Object



153
154
155
156
157
# File 'lib/thredded/database_seeder.rb', line 153

def with_mentions(post, mentions_count: rand(3))
  return post if mentions_count.zero?

  ([post] + Array.new(mentions_count).map { user_mention(@users.sample) }).join(' ')
end