Skip to content

Commit 908317d

Browse files
dblockCopilot
andcommitted
Document custom Team fields and Rails reloading
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent df1960b commit 908317d

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### 2.3.0 (Next)
44

5+
* [#186](https://github.com/slack-ruby/slack-ruby-bot-server/pull/186): Document persisted custom Team attributes for both adapters and Rails concern loading/reloading - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/apps/copilot-swe-agent).
56
* [#183](https://github.com/slack-ruby/slack-ruby-bot-server/pull/183): Add a `config.server_pages` block to configure page middleware options centrally without changing the installed library's defaults - [@dblock](https://github.com/dblock), [@Copilot](https://github.com/apps/copilot-swe-agent).
67
* Your contribution here.
78

‎README.md‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ Build a complete Slack bot service with Slack button integration, in Ruby.
1717
- [Storage](#storage)
1818
- [MongoDB](#mongodb)
1919
- [ActiveRecord](#activerecord)
20+
- [Extending Team](#extending-team)
21+
- [Mongoid Attributes](#mongoid-attributes)
22+
- [Active Record Attributes](#active-record-attributes)
23+
- [Rails Loading and Reloading](#rails-loading-and-reloading)
2024
- [OAuth Version and Scopes](#oauth-version-and-scopes)
2125
- [Slack App](#slack-app)
2226
- [API](#api)
@@ -108,6 +112,76 @@ db_config = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0.pre1'
108112
ActiveRecord::Base.establish_connection(db_config)
109113
```
110114

115+
#### Extending Team
116+
117+
The installation model is the top-level `::Team` class for both adapters, not `SlackRubyBotServer::Models::Team`. Load `slack-ruby-bot-server` before extending it. The model already includes its database adapter and timestamps; do not include them again or declare a different superclass.
118+
119+
##### Mongoid Attributes
120+
121+
Add fields by reopening the existing class in an application file, for example `lib/team_extensions.rb`:
122+
123+
```ruby
124+
require 'slack-ruby-bot-server'
125+
126+
class Team
127+
field :subscription_plan, type: String, default: 'free'
128+
129+
def paid_plan?
130+
subscription_plan == 'paid'
131+
end
132+
end
133+
```
134+
135+
Require that file from your startup code after loading the framework and before serving requests or starting the service. Mongoid does not require a schema migration for the new field.
136+
137+
##### Active Record Attributes
138+
139+
Add a column to the existing `teams` table with an application migration. Use your application's migration version; this example is also compatible with older supported Active Record versions:
140+
141+
```ruby
142+
class AddSubscriptionPlanToTeams < ActiveRecord::Migration[6.0]
143+
def change
144+
add_column :teams, :subscription_plan, :string, default: 'free', null: false
145+
end
146+
end
147+
```
148+
149+
Run the migration before code uses the attribute. Active Record provides its reader and writer from the column; do not use `attr_accessor`, which would bypass persistence. Add methods by reopening `class Team` after loading the framework, as above, but omit the Mongoid-only `field` declaration.
150+
151+
##### Rails Loading and Reloading
152+
153+
Putting another `app/models/team.rb` in a Rails app is not a reliable way to extend a class already loaded by a gem. Put reloadable behavior in a concern instead:
154+
155+
```ruby
156+
# app/models/concerns/team_extensions.rb
157+
module TeamExtensions
158+
extend ActiveSupport::Concern
159+
160+
def paid_plan?
161+
subscription_plan == 'paid'
162+
end
163+
end
164+
```
165+
166+
Include it in `::Team` from a reloader callback, rather than autoloading the concern directly during initializer execution:
167+
168+
```ruby
169+
# config/initializers/team_extensions.rb
170+
require 'slack-ruby-bot-server'
171+
172+
if SlackRubyBotServer.config.mongoid?
173+
::Team.field :subscription_plan, type: String, default: 'free'
174+
end
175+
176+
Rails.application.config.to_prepare do
177+
::Team.include(TeamExtensions)
178+
end
179+
```
180+
181+
With Active Record, use the migration above instead of declaring a field in the initializer. The callback runs at boot and after development reloads; including the same concern more than once is safe. Keep one-time field declarations outside the callback. Do not query the database or swallow database errors just to attach methods: the extension can be loaded before the `teams` table exists.
182+
183+
The framework currently owns the global `Team` constant. An unrelated application model with the same name is a separate [name-collision limitation](https://github.com/slack-ruby/slack-ruby-bot-server/pull/83), not an extension mechanism.
184+
111185
### OAuth Version and Scopes
112186

113187
Configure your app's [OAuth version](https://api.slack.com/authentication/oauth-v2) and [scopes](https://api.slack.com/legacy/oauth-scopes) as needed by your application.

0 commit comments

Comments
 (0)