# Discourse Plugins and Rails 6 config/initializers Question

**URL:** https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373
**Category:** Development
**Created:** [October 27, 2020, 11:34am UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373 "2020-10-27T11:34:52Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [October 27, 2020, 11:34am UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/1 "2020-10-27T11:34:52Z")

</div>

Hey Discourse Plugin Gurus,

Just a quick question about Discourse plugins and Rails initializers.

If a Discourse plugin has a directory called “config” and a subdirectory under “config” called “initializers” does the Discourse Rails app read all the plugin initializer files under the “initializers” directory like Rails 6 does?

The reason I ask is that I’m in the middle of writing a “back office” Rails 6 application (Rails only, no EmberJS or other JS framework on top) from scratch for a client and I have a directory under initializers like this:

```plaintext
./config/initializers/client/

```

… and all the initializers unique to the client are in the “client” subdirectory.

Rails 6 reads all files under the standard initializers directory (even subdirectories); and so I was wondering if Discourse plugins, with a similar directory structure for initializers, will behave as Rails 6 does and read all the initializers in the plugin in a manner like this:

```plaintext
./plugins/my_plugin/config/initializers/myclient/
      client_initializer1.rb
      client_initializer2.rb
      client_initializer2.rb

```

… without registering these assets in the plugin.rb file?

Thanks!

PS: I looked in about 10 Discourse plugins on GitHub and none of the ones I looked at had initializers under the config directory. That’s why I decided to post the question (and my Rails dev environment is not set up for Discourse at the moment, it’s all setup for the client).

---

<div class="post-metadata">

### Author: ![hawm](https://avatars.discourse-cdn.com/v4/letter/h/f07891/32.png) [@hawm](https://meta.discourse.org/u/hawm)
#### Post date: [October 27, 2020, 12:45pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/2 "2020-10-27T12:45:18Z")

</div>

I also want to know the Discourse Plugin different than a common Rails Engine. I were just look into the source code but didn’t get much.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 12:47pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/3 "2020-10-27T12:47:18Z")

</div>

After skimming through this [Ruby on Rails Guides: Configuring Rails Applications](https://guides.rubyonrails.org/v3.2/configuring.html#using-initializer-files)  
I think plugin.rb is kind of the same thing. Most of the plugins that are decent size use it as an entry point to the logic rather than the logic itself.

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [October 27, 2020, 1:27pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/4 "2020-10-27T13:27:16Z")

</div>

> [@fzngagan](#):
>
> After skimming through this [Ruby on Rails Guides: Configuring Rails Applications](https://guides.rubyonrails.org/v3.2/configuring.html#using-initializer-files)

Yeah, I read that Rails guide a lot lately. Basically, I’m “OK” with how Rails 6 config works (still learning, but getting more and more comfortable each day).

I am just wondering if we can use the same structure in a Discourse plugin (for initializers), if Rails will read the initializers in the subdirectories like they do in Rails 6; or do we have to register the plugin initializer directory as a configuration “asset” (for a lack of a better word) in plugin.rb.

I was reading up on Rails plugins yesterday and comparing a bit as well.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 1:29pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/5 "2020-10-27T13:29:45Z")

</div>

> [@neounix](#):
>
> I am just wondering if we can use the same structure in a Discourse plugin (for initializers), if Rails will read the initializers in the subdirectories like they do in Rails 6; or do we have to register the plugin initializer directory as a configuration “asset” (for a lack of a better word) in plugin.rb.

Discourse doesn’t read any ruby file other than plugin.rb as far as I know. It does read the js and config files. All the ruby files have to be `require`d in plugin.rb.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [October 27, 2020, 1:35pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/6 "2020-10-27T13:35:16Z")

</div>

I believe so too.

You load any additional Ruby files you need from within plugin.rb.

Here’s an example from the Follow plugin:

> <https://github.com/discourse/discourse-follow/blob/0290c428210199e35972e17746fefa8c67f24070/plugin.rb#L31>

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [October 27, 2020, 1:35pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/7 "2020-10-27T13:35:30Z")

</div>

> [@fzngagan](#):
>
> Discourse doesn’t read any ruby file other than plugin.rb as far as I know. It does read the js and config files. All the ruby files have to be `require` d in plugin.rb.

That’s kinda my impression reading though a number of Discourse plugins on GitHub.

Seems Discourse only reads plugin.rb and we have to load all other Ruby files we might want, like initializers, in plugin.rb.

However, I was hoping I was wrong and there might be a “deeper” integration of Discourse plugins and Rails; as I have been getting very spoiled on how great Rails 6 is.

> [@merefield](#):
>
> I believe so too.
> 
> You load any additional Ruby files you need from within plugin.rb.
> 
> Here’s an example from Follow plugin:

Thanks for confirming as well.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 1:41pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/8 "2020-10-27T13:41:24Z")

</div>

> [@neounix](#):
>
> However, I was hoping I was wrong and there might be a “deeper” integration of Discourse plugins and Rails; as I have been getting very spoiled on how great Rails 6 is.

I think there should be a way to require initializer code in plugin.rb too.  
Did you try this in plugin.rb

```plaintext
Rails.application.config.before_initialize do
  # initialization code goes here
end

```

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [October 27, 2020, 1:45pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/9 "2020-10-27T13:45:50Z")

</div>

> [@fzngagan](#):
>
> I think there should be a way to require initializer code in plugin.rb too.  
> Did you try this in plugin.rb

Yes, that is not a problem calling and loading the initializers in plugin.rb.

The reason for my question was because I am currently writing a fairly large Rails 6 app for a business, converting their legacy back office scripts (over a few decades) to a Rails app, and to add initializers, I just have a subdirectory under `config/initializers` (in Rails) and all my initializer files are included so nicely without any need to write any code to include these files in Rails.

Thanks for all your replies. Much appreciated!

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 1:52pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/10 "2020-10-27T13:52:24Z")

</div>

Yeah, I would love those rails perks being ported to discourse plugins. One of my personal favourite would be able to live reload the ruby files without restarting the server.

---

<div class="post-metadata">

### Author: ![markvanlan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markvanlan/32/160087_2.png) [@markvanlan](https://meta.discourse.org/u/markvanlan)
#### Post date: [October 27, 2020, 1:58pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/11 "2020-10-27T13:58:35Z")

</div>

> [@fzngagan](#):
>
> live reload the ruby files without restarting the server

This is what [reloadable\_patch](https://github.com/discourse/discourse/blob/66402abe9a093d96e3e8e9e40e9b396d61707719/lib/plugin/instance.rb#L938) is for. If you wrap ruby class changes in `reloadable_patch`, it should live reload!

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 2:00pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/12 "2020-10-27T14:00:50Z")

</div>

> [@markvanlan](#):
>
> If you wrap ruby class changes in `reloadable_patch` , it should live reload!

Can I wrap the whole plugin.rb file inside it for dev? More seriously, how far can we go with it?

Also, adding new files or changing any yml files needs a server restart right?

---

<div class="post-metadata">

### Author: ![markvanlan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markvanlan/32/160087_2.png) [@markvanlan](https://meta.discourse.org/u/markvanlan)
#### Post date: [October 27, 2020, 2:04pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/13 "2020-10-27T14:04:58Z")

</div>

You shouldn’t have to do a reloadable\_patch for **everything**. Many of the methods defined in `instance.rb` to make plugin development easy, use reloadable\_patch internally like `add_to_serializer`.

> <https://github.com/discourse/discourse/blob/66402abe9a093d96e3e8e9e40e9b396d61707719/lib/plugin/instance.rb#L124>

Ideally our plugin api is good enough that you shouldn’t have to do an insane amount of reloadable\_patch’ing.

> [@fzngagan](#):
>
> Also, adding new files or changing any yml files needs a server restart right?

Yeah, this is true. I wonder if anything can be done about the yml file changes; that one annoys me personally.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 2:11pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/14 "2020-10-27T14:11:59Z")

</div>

> [@markvanlan](#):
>
> You shouldn’t have to do a reloadable\_patch for **everything**.

True that. I didn’t know `reloadable_patch` was meant for supporting live reloading. I can think of many use cases apart from where discourse already uses that. i.e.

```plaintext
reloadable_patch do
 require 'x/y/z'
end

```

or monkey patches.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 27, 2020, 2:18pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/15 "2020-10-27T14:18:53Z")

</div>

> [@markvanlan](#):
>
> Many of the methods defined in `instance.rb` to make plugin development easy, use reloadable\_patch internally like `add_to_serializer` .

I think removing or adding such a function would still be a problem coz `reloadable_patch` is called inside the function.

In any case, it helps a lot.

---

<div class="post-metadata">

### Author: ![markvanlan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markvanlan/32/160087_2.png) [@markvanlan](https://meta.discourse.org/u/markvanlan)
#### Post date: [October 27, 2020, 3:25pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/16 "2020-10-27T15:25:13Z")

</div>

I started looking into live-reloading yml changes, and it actually does work. Plugins may break this live-reloading if they are not properly using `reloadable_patch`, but once all your plugins can safely reload, so will your yml changes.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [November 3, 2020, 9:51am UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/17 "2020-11-03T09:51:53Z")

</div>

It would be super helpful though, if you could describe the exact steps to use reloadable patch.

Here’s what I tried without much luck(I’m missing something for sure)

```plaintext
after_initialize do
    add_to_serializer(:topic_view, :check, false) do
        puts 'nocheck'
    end
end

```

Once the server starts, and I change `nocheck` to `check`, it still prints `nocheck` after I reload the topic route.

```plaintext
after_initialize do
    reloadable_patch do |plugin|
        puts 'nocheck'
    end
end

```

Still no luck when I reload any page after changing the string under puts.

---

<div class="post-metadata">

### Author: ![markvanlan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markvanlan/32/160087_2.png) [@markvanlan](https://meta.discourse.org/u/markvanlan)
#### Post date: [November 3, 2020, 2:40pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/20 "2020-11-03T14:40:41Z")

</div>

I guess I have mislead you in posts above. `reloadable_patch` is helpful for discourse development, but @david explained it’s use very well:

* * *

Anything inside the `after_initialize` block of plugin.rb is only loaded [during application boot](https://github.com/discourse/discourse/blob/5140ec9acf29df220ec00cc6a704b73773a86bdc/config/application.rb#L342-L342), and not on subsequent reloads.

So, assuming you want to add something to the user serializer. The normal behavior would be like:

**At boot:**

- Discourse loads `user_serializer.rb`
- Discourse loads `plugin.rb` , which has an override for `user_serializer`

**At reload:**

- Discourse reloads `user_serializer.rb`
- (the plugin.rb patch is not reloaded, the plugin override is lost)

With our `reloadable_patch` system:

**At boot:**

- Discourse loads `user_serializer.rb`
- Discourse loads `plugin.rb` and registers the `reloadable_patch` for the user\_serializer
- The reloadable patches are executed

**At reload:**

- Discourse reloads `user_serlializer.rb`
- The reloadable patches are executed
- (yay, the plugin override is still working)

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [November 4, 2020, 10:35am UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/21 "2020-11-04T10:35:25Z")

</div>

> [@markvanlan](#):
>
> Anything inside the `after_initialize` block of plugin.rb is only loaded [during application boot](https://github.com/discourse/discourse/blob/5140ec9acf29df220ec00cc6a704b73773a86bdc/config/application.rb#L342-L342), and not on subsequent reloads.

This is describing a core Rails property, which is not germane to Discourse.

In Rails, all initializers are loaded only when Rails starts up, so any plugin which executes code based on the initializer, like “after\_initializer” will only execute on Rails start up or restart (please correct me if wrong).

> **[Ruby on Rails Guides: Configuring Rails Applications](https://guides.rubyonrails.org/v2.3/configuring.html)**

The reason I am familiar with this is that I am currently building a Rails application for a client and I have written a lot of initializers for various tasks (booleans, static arrays, etc). In each case, if we change any code in a Rails initializer, it is necessary to restart Rails (“Control c, rails s in dev”) to get the new values in the initializers into the Rails app.

Please correct me if I am wrong! Thanks.

Sometimes, I think it might be a bit confusing to some Discourse plugin developers, especially those developers who primarily work on Discourse plugins and not with Rails applications in general, when we write “Discourse does this” or “Discourse does that” when what we are really describing is a core Rails function or property not necessarily germane to Discourse, per se.

Rails 6 reads all files in the `config/initializers` directory (and all `config/initializers` subdirectories) **only** when Rails starts up. Likewise (not 100% sure about plugins) a Discourse plugin with code dependent on `after_initialize` will (kindly confirm anyone?) only be loaded by the Rails app when Rails starts up or restarts, because this is a fundamental property of the Rails boot process.

My guess is that everyone here already knows this who works on Rails. I only am starting to know these details (and feel I have a long way to go to be an expert); because I’m currently working on a Rails application every day (these days), which by-the-way, I now wish I would have starting working with Rails a decade ago because coming from a LAMP dev background, I find Rails so very much better (easy and fun to work with).

I have become a major Rails fan this year and I am very grateful to Discourse to starting me down that path.

Again, please correct me if I am wrong! Thanks. I’m trying to be more expert in Rails.

---

<div class="post-metadata">

### Author: ![markvanlan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markvanlan/32/160087_2.png) [@markvanlan](https://meta.discourse.org/u/markvanlan)
#### Post date: [November 4, 2020, 3:44pm UTC](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373/22 "2020-11-04T15:44:14Z")

</div>

> [@neounix](#):
>
> Likewise (not 100% sure about plugins) a Discourse plugin with code dependent on `after_initialize` will (kindly confirm anyone?) only be loaded by the Rails app when Rails starts up or restarts, because this is a fundamental property of the Rails boot process.

Yep! This is correct as is your understanding of Rails initializers.

I too am a huge Rails fan 🙂

[Next page](https://meta.discourse.org/t/discourse-plugins-and-rails-6-config-initializers-question/168373.md?page=2)
