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



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

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



98
99
100
# File 'lib/thredded/database_seeder.rb', line 98

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
# 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|
    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



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

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: 1 + rand(3), messageboard: messageboard)
    Posts.new(self).create(count: (1..2), topics: topics)
  end
end

#fake_post_contentsObject



135
136
137
# File 'lib/thredded/database_seeder.rb', line 135

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

#first_messageboardObject



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

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

#first_userObject



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

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

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



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

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



125
126
127
128
# File 'lib/thredded/database_seeder.rb', line 125

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

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



189
190
191
# File 'lib/thredded/database_seeder.rb', line 189

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

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



193
194
195
# File 'lib/thredded/database_seeder.rb', line 193

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

#private_topics(count: 1) ⇒ Object



185
186
187
# File 'lib/thredded/database_seeder.rb', line 185

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



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

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



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

def read_topic(topic, user_id)
  read_state = Thredded::UserTopicReadState.find_or_initialize_by(user_id: user_id, postable_id: topic.id)
  if rand(2).zero?
    read_state.update!(read_at: topic.updated_at)
  else
    read_state.update!(read_at: topic.posts.order_newest_first.first(2).last.created_at)
  end
end

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



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

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



181
182
183
# File 'lib/thredded/database_seeder.rb', line 181

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

#user_detailsObject



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

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

#users(count: 1) ⇒ Object



143
144
145
# File 'lib/thredded/database_seeder.rb', line 143

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