What's the best way to store data with a plugin?

I’m planning to store data with a plugin, of literally 1 value, a topic id. What’s the best way to do this?

Thanks.

If you only need to store a single Topic ID (like a configurable value), the simplest Discourse-native way is using a SiteSetting.
You also get a built-in admin UI automatically.

config/settings.yml:

plugins:
  my_plugin_enabled:
    default: true
    client: false

  my_plugin_topic_id:
    default: 0
    client: false
    type: topic      # gives you a topic selector in admin UI

In your Ruby plugin code:

topic_id = SiteSetting.my_plugin_topic_id
topic = Topic.find_by(id: topic_id)

If you prefer to store it programmatically (not exposed as a setting),
PluginStore is also fine for a single key-value:

store = PluginStore.new("my_plugin")
store.set("topic_id", some_topic_id)

topic_id = store.get("topic_id")
3 likes

I think PluginStore is the most suitable way. A site setting will not fit this use case. Thanks!

1 like

Your question reminded me of something I recently read on Meta.

2 likes

I was just about to start - thanks for bringing this up. It seems like making a whole DB table for 1 value is overkill, and completely unnecessary. Any ideas?

1 like

What is the reason why you don’t want a site setting? It could be hidden so admins won’t see it, kind of like the IDs for the special topics in core, like TOS.

My use case is this: any topic or post created from the time the plugin is enabled is synced and stored somewhere else. But topics before that aren’t, so I have to run a job to sync those, perhaps in batches of 100. I need to store the lowest topic I’d so the next batch is that minus 100, and so on.

Chatbot does something very similar.

Here is the migration:

This only ever has one record :slight_smile:

3 likes

That’s good - at least I’m not the only one :laughing:… my next hurdle is how to run the migration - in a dev Discourse site or something else… wouldn’t running the migration then just add to Discourse’s migrations directory? Should I copy the file manually? Thanks.

You place it, as per all plugin migrations, in the plugin (just like Chatbot above).

You run migrations with LOAD_PLUGINS=1 rake db:migrate

Read up on migrations here:

2 likes

I know, the only thing I don’t get is that I’m supposed to write the minute and second manually as I create the file?

Read the guide. Not convinced you’ve read it past section 1. :wink:

1 like

I think we should probably deprecate PluginStore cc @david , it just leads to pain down the line.

Creating new tables and models are the way to go imo.

Post and Topic custom fields can work for this. Downside though is indexing can be tricky cause it does not feel right to add indexes to core tables. Which is back to just introducing new tables.

1 like