Class: Thredded::DatabaseSeeder

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

Overview

rubocop:disable Metrics/ClassLength

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LogTime

included, #log_time, #print_time_diff

Class Method Details

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


86
87
88
89
90
91
92
93
94
# File 'lib/thredded/database_seeder.rb', line 86

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


96
97
98
# File 'lib/thredded/database_seeder.rb', line 96

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

.with_seeder_tweaksObject

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


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/thredded/database_seeder.rb', line 59

def self.with_seeder_tweaks  # Disable callbacks to avoid creating notifications and performing unnecessary updates

  DISABLE_COUNTER_CACHE.each do |klass|
    klass.send(:alias_method, :original_each_counter_cached_associations, :each_counter_cached_associations)
    klass.send(:define_method, :each_counter_cached_associations) {}
  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|
    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
  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


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/thredded/database_seeder.rb', line 155

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


133
134
135
# File 'lib/thredded/database_seeder.rb', line 133

def fake_post_contents
  @fake_post_contents ? @fake_post_contents.sample : FakeContent.post_content
end

#first_messageboardObject


151
152
153
# File 'lib/thredded/database_seeder.rb', line 151

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

#first_userObject


137
138
139
# File 'lib/thredded/database_seeder.rb', line 137

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

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


208
209
210
211
212
# File 'lib/thredded/database_seeder.rb', line 208

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


123
124
125
126
# File 'lib/thredded/database_seeder.rb', line 123

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

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


187
188
189
# File 'lib/thredded/database_seeder.rb', line 187

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

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


191
192
193
# File 'lib/thredded/database_seeder.rb', line 191

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

#private_topics(count: 1) ⇒ Object


183
184
185
# File 'lib/thredded/database_seeder.rb', line 183

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


225
226
227
228
229
# File 'lib/thredded/database_seeder.rb', line 225

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


231
232
233
234
235
236
237
238
239
# File 'lib/thredded/database_seeder.rb', line 231

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


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/thredded/database_seeder.rb', line 100

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


179
180
181
# File 'lib/thredded/database_seeder.rb', line 179

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

#user_detailsObject


145
146
147
148
149
# File 'lib/thredded/database_seeder.rb', line 145

def user_details
  @user_details ||= users.each_with_object({}) do |user, hash|
    hash[user] = user.thredded_user_detail
  end
end

#users(count: 1) ⇒ Object


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

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