If the Lobster replacement class isn't in the global scope, the existing
Lobsters can't refer to it. But if it's in the global scope, the DOM isn't yet
loaded for it to read the current username. When the old class is entirely
replaced, insantiation of the class can move back into onPageLoad().
old Story.filter_tags([1, 2, 3]):
Story.where.not( Tagging.select('TRUE').where('taggings.story_id = stories.id').where(tag_id: [1, 2, 3]).arel.exists)
SELECT `stories`.* FROM `stories` WHERE NOT (EXISTS (SELECT TRUE FROM `taggings` WHERE (taggings.story_id = stories.id) AND `taggings`.`tag_id` IN (1, 2, 3)))
new Story.filter_tags([1, 2, 3]):
Story.where(Story.arel_table[:id].not_in(Tagging.where(tag_id: [1, 2, 3]).select(:story_id).arel))
SELECT `stories`.* FROM `stories` WHERE `stories`.`id` NOT IN (SELECT `taggings`.`story_id` FROM `taggings` WHERE `taggings`.`tag_id` IN (1, 2, 3))
same story for Story.filter_tags_for(1):
Story.where(Story.arel_table[:id].not_in(Tagging.joins(tag: :tag_filters).where(tag_filters: { user_id: 1 }).select(:story_id).arel))
SELECT `stories`.* FROM `stories` WHERE `stories`.`id` NOT IN (SELECT `taggings`.`story_id` FROM `taggings` INNER JOIN `tags` ON `tags`.`id` = `taggings`.`tag_id` INNER JOIN `tag_filters` ON `tag_filters`.`tag_id` = `tags`.`id` WHERE `tag_filters`.`user_id` = 78)
So this is a clear improvement... but the EXPLAIN is exactly the same, MariaDB
recognized the opportunity:
+------+--------------+----------+-------+------------------------------------+-----------------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+----------+-------+------------------------------------+-----------------+---------+------+-------+--------------------------+
| 1 | PRIMARY | stories | ALL | NULL | NULL | NULL | NULL | 85056 | Using where |
| 2 | MATERIALIZED | taggings | index | story_id_tag_id,taggings_tag_id_fk | story_id_tag_id | 16 | NULL | 1 | Using where; Using index |
+------+--------------+----------+-------+------------------------------------+-----------------+---------+------+-------+--------------------------+
So this is a no-op on MariaDB, but I'm making the change because the
ActiveRecord is easier to read. Credit to Aaron Francis and Colleen Schnettler.