webring-rails 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +10 -544
- data/app/controllers/webring/members_controller.rb +13 -12
- data/app/controllers/webring/membership_requests_controller.rb +23 -0
- data/app/models/concerns/webring/membership_request_actions.rb +28 -0
- data/app/models/webring/member.rb +1 -6
- data/app/models/webring/membership_request.rb +16 -0
- data/lib/generators/USAGE +17 -4
- data/lib/generators/webring/install/templates/AFTER_INSTALL +22 -3
- data/lib/generators/webring/member/member_generator.rb +1 -0
- data/lib/generators/webring/member/templates/AFTER_INSTALL +4 -11
- data/lib/generators/webring/member/templates/migration.rb +6 -5
- data/lib/generators/webring/member/templates/model.rb +1 -6
- data/lib/generators/webring/membership_request/membership_request_generator.rb +73 -0
- data/lib/generators/webring/membership_request/templates/AFTER_INSTALL +41 -0
- data/lib/generators/webring/membership_request/templates/migration.rb +15 -0
- data/lib/generators/webring/membership_request/templates/model.rb +29 -0
- data/lib/generators/webring/membership_request/templates/relations_migration.rb +5 -0
- data/lib/generators/webring/membership_requests_controller/membership_requests_controller_generator.rb +44 -0
- data/lib/generators/webring/membership_requests_controller/templates/membership_requests_controller.rb +23 -0
- data/lib/generators/webring/{controller/controller_generator.rb → navigation_controller/navigation_controller_generator.rb} +1 -1
- data/lib/generators/webring_generator.rb +1 -1
- data/lib/webring/version.rb +1 -1
- data/lib/webring-rails.rb +0 -2
- metadata +14 -4
- /data/lib/generators/webring/{controller → navigation_controller}/templates/navigation_controller.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85902566f8117884214215614a8dc3b89c0065d797fb0c4ab2863e4af823185b
|
4
|
+
data.tar.gz: 0c783b549c5e21ad829677d17d6413a083bed29b47b3dc75eacf08dd6ec205b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f7df96b07dcbacf10d092ffd1a9c3419c2a096517ae1986b1a13970fa3bb85114aff19bb05b6e9002ee87d9710201569c16254a0fbcf8ca31936938ad6b19de
|
7
|
+
data.tar.gz: 076dbbe45eacad535ae1940e229c6fc2abfa94f7afcea0f13aee58b437a62bfdb445e120dc090748f34960f8d09eca45fd8f9cbd8fc2ec94f6755f9a90757fac
|
data/README.md
CHANGED
@@ -4,71 +4,19 @@
|
|
4
4
|
|
5
5
|
Webring for Rails (webring_rails) is a flexible engine for creating and managing a webring system in your Ruby on Rails application. A webring is a collection of websites linked together in a circular structure, allowing visitors to navigate from one site to another.
|
6
6
|
|
7
|
-
## Table of Contents
|
8
|
-
|
9
|
-
- [Features](#features)
|
10
|
-
- [Requirements](#requirements)
|
11
|
-
- [Installation](#installation)
|
12
|
-
- [Quick Start](#quick-start)
|
13
|
-
- [Manual Setup](#manual-setup)
|
14
|
-
- [Configuration Options](#configuration-options)
|
15
|
-
- [Setting Up Your Host Application](#setting-up-your-host-application)
|
16
|
-
- [Usage](#usage)
|
17
|
-
- [Generators](#generators)
|
18
|
-
- [Installation Generator](#installation-generator)
|
19
|
-
- [Member Model Generator](#member-model-generator)
|
20
|
-
- [Navigation Controller Generator](#navigation-controller-generator)
|
21
|
-
- [Basic Implementation](#basic-implementation)
|
22
|
-
- [Customizing Your Webring](#customizing-your-webring)
|
23
|
-
- [Models](#models)
|
24
|
-
- [Webring::Member](#webringmember)
|
25
|
-
- [Modules](#modules)
|
26
|
-
- [Webring::Navigation](#webringnavigation)
|
27
|
-
- [Key Features](#key-features)
|
28
|
-
- [Available Methods](#available-methods)
|
29
|
-
- [Usage in Models](#usage-in-models)
|
30
|
-
- [Implementation Example](#implementation-example)
|
31
|
-
- [Customizing Navigation Behavior](#customizing-navigation-behavior)
|
32
|
-
- [Controllers](#controllers)
|
33
|
-
- [Webring::NavigationController](#webringnavigationcontroller)
|
34
|
-
- [How to Use the Navigation Controller](#how-to-use-the-navigation-controller)
|
35
|
-
- [Customizing Navigation Behavior](#customizing-navigation-behavior-1)
|
36
|
-
- [Webring::MembersController](#webringmemberscontroller)
|
37
|
-
- [Widget](#widget)
|
38
|
-
- [Webring::WidgetController](#webringwidgetcontroller)
|
39
|
-
- [Widget.js](#widgetjs)
|
40
|
-
- [How to Use the Widget](#how-to-use-the-widget)
|
41
|
-
- [Widget Customization Options](#widget-customization-options)
|
42
|
-
- [Example With All Options](#example-with-all-options)
|
43
|
-
- [Multiple Widgets on the Same Page](#multiple-widgets-on-the-same-page)
|
44
|
-
- [Development](#development)
|
45
|
-
- [Migrations](#migrations)
|
46
|
-
- [Testing](#testing)
|
47
|
-
- [Contributing](#contributing)
|
48
|
-
- [License](#license)
|
49
|
-
|
50
7
|
## Features
|
51
8
|
|
52
|
-
Webring for Rails provides the following features:
|
53
|
-
|
54
9
|
- Complete MVC structure for managing webring members
|
55
10
|
- Circular navigation system between member websites
|
56
11
|
- UID-based member identification for security
|
57
12
|
- Embeddable JavaScript widget for easy member site integration
|
58
13
|
- Customizable widget appearance and behavior
|
14
|
+
- Optional membership request system for sites to apply to join the webring
|
59
15
|
- Generators for easy setup and customization
|
60
16
|
- Extensible architecture for adding custom features
|
61
17
|
|
62
|
-
## Requirements
|
63
|
-
|
64
|
-
- Ruby 2.7.0 or later
|
65
|
-
- Rails 6.0 or later
|
66
|
-
- ActiveRecord-compatible database (MySQL, PostgreSQL, SQLite)
|
67
|
-
|
68
18
|
## Installation
|
69
19
|
|
70
|
-
### Quick Start
|
71
|
-
|
72
20
|
Add this line to your application's Gemfile:
|
73
21
|
|
74
22
|
```ruby
|
@@ -88,510 +36,28 @@ rails generate webring:install
|
|
88
36
|
rails generate webring:member
|
89
37
|
|
90
38
|
# Create the navigation controller
|
91
|
-
rails generate webring:controller
|
92
|
-
|
93
|
-
# Run migrations
|
94
|
-
rails db:migrate
|
95
|
-
```
|
96
|
-
|
97
|
-
### Manual Setup
|
98
|
-
|
99
|
-
If you prefer to set things up step by step:
|
100
|
-
|
101
|
-
1. Add the gem to your Gemfile:
|
102
|
-
|
103
|
-
```ruby
|
104
|
-
gem 'webring_rails'
|
105
|
-
```
|
106
|
-
|
107
|
-
2. Install the gem:
|
108
|
-
|
109
|
-
```bash
|
110
|
-
bundle install
|
111
|
-
```
|
112
|
-
|
113
|
-
3. Mount the engine in your routes:
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
# config/routes.rb
|
117
|
-
Rails.application.routes.draw do
|
118
|
-
mount Webring::Engine => "/webring"
|
119
|
-
|
120
|
-
# Your other routes...
|
121
|
-
end
|
39
|
+
rails generate webring:controller:navigation
|
122
40
|
```
|
123
41
|
|
124
|
-
|
42
|
+
### Optional Features
|
125
43
|
|
126
44
|
```bash
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
5. Configure your migration:
|
131
|
-
|
132
|
-
```ruby
|
133
|
-
class CreateWebringMembers < ActiveRecord::Migration[6.0]
|
134
|
-
def change
|
135
|
-
create_table :webring_members do |t|
|
136
|
-
t.string :uid, null: false, index: { unique: true }
|
137
|
-
t.string :name, null: false, index: { unique: true }
|
138
|
-
t.string :url, null: false, index: { unique: true }
|
45
|
+
# Enable the membership request system
|
46
|
+
rails generate webring:membership_request
|
139
47
|
|
140
|
-
|
141
|
-
|
142
|
-
end
|
143
|
-
end
|
48
|
+
# Add membership request controller and routes
|
49
|
+
rails generate webring:controller:membership_requests
|
144
50
|
```
|
145
51
|
|
146
|
-
|
52
|
+
Finally, run the migrations:
|
147
53
|
|
148
54
|
```bash
|
149
55
|
rails db:migrate
|
150
56
|
```
|
151
57
|
|
152
|
-
|
153
|
-
|
154
|
-
You can configure the webring engine by creating an initializer:
|
155
|
-
|
156
|
-
```ruby
|
157
|
-
# config/initializers/webring.rb
|
158
|
-
Webring.setup do |config|
|
159
|
-
# Set the primary key type (uuid recommended for production)
|
160
|
-
config.primary_key_type = :uuid
|
161
|
-
end
|
162
|
-
```
|
163
|
-
|
164
|
-
### Setting Up Your Host Application
|
165
|
-
|
166
|
-
To properly integrate the webring in your host application:
|
167
|
-
|
168
|
-
1. Set up default URL options for mailers in each environment:
|
169
|
-
|
170
|
-
```ruby
|
171
|
-
# config/environments/development.rb
|
172
|
-
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
173
|
-
```
|
174
|
-
|
175
|
-
2. Add root route in your application:
|
176
|
-
|
177
|
-
```ruby
|
178
|
-
# config/routes.rb
|
179
|
-
root to: 'home#index'
|
180
|
-
```
|
181
|
-
|
182
|
-
## Usage
|
183
|
-
|
184
|
-
### Generators
|
185
|
-
|
186
|
-
WebringRails provides several generators to help you set up webring functionality in your application.
|
187
|
-
|
188
|
-
> [!IMPORTANT]
|
189
|
-
> Make sure to run the generators in the order listed below for the best setup experience.
|
190
|
-
|
191
|
-
#### Installation Generator
|
192
|
-
|
193
|
-
```bash
|
194
|
-
rails generate webring:install
|
195
|
-
```
|
196
|
-
|
197
|
-
This generator:
|
198
|
-
- Mounts the Webring engine in your routes.rb
|
199
|
-
|
200
|
-
#### Member Model Generator
|
201
|
-
|
202
|
-
```bash
|
203
|
-
rails generate webring:member
|
204
|
-
```
|
205
|
-
|
206
|
-
This generator:
|
207
|
-
- Creates the Webring::Member model with uid, name and url fields
|
208
|
-
- Creates a migration for the members table
|
209
|
-
- Adds member routes to your routes.rb file
|
210
|
-
|
211
|
-
#### Navigation Controller Generator
|
212
|
-
|
213
|
-
```bash
|
214
|
-
rails generate webring:controller
|
215
|
-
```
|
216
|
-
|
217
|
-
This generator:
|
218
|
-
- Creates the Webring::NavigationController with '/next', '/previous', and '/random' actions
|
219
|
-
- Adds navigation routes to your routes.rb file
|
220
|
-
|
221
|
-
### Basic Implementation
|
222
|
-
|
223
|
-
After setting up the gem, you'll need to add members to your webring:
|
224
|
-
|
225
|
-
```ruby
|
226
|
-
# Through the console or in a seed file
|
227
|
-
Webring::Member.create(name: "My Awesome Site", url: "https://myawesomesite.com")
|
228
|
-
Webring::Member.create(name: "Another Cool Site", url: "https://anothercoolsite.com")
|
229
|
-
```
|
230
|
-
|
231
|
-
### Customizing Your Webring
|
232
|
-
|
233
|
-
You can customize various aspects of your webring:
|
234
|
-
|
235
|
-
1. Create custom views:
|
236
|
-
|
237
|
-
```bash
|
238
|
-
rails generate webring:views
|
239
|
-
```
|
240
|
-
|
241
|
-
2. Create a custom navigation controller:
|
242
|
-
|
243
|
-
```ruby
|
244
|
-
# app/controllers/custom_navigation_controller.rb
|
245
|
-
class CustomNavigationController < Webring::NavigationController
|
246
|
-
def next
|
247
|
-
# Your custom implementation
|
248
|
-
super
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
# config/routes.rb
|
253
|
-
get 'webring/next', to: 'custom_navigation#next'
|
254
|
-
```
|
255
|
-
|
256
|
-
## Models
|
257
|
-
|
258
|
-
### Webring::Member
|
259
|
-
|
260
|
-
> [!NOTE]
|
261
|
-
> The Member model is the core component of your webring, representing each site in the ring.
|
262
|
-
|
263
|
-
The Member model includes:
|
264
|
-
|
265
|
-
- Validations for presence and uniqueness of `url`, uniqueness of `name`, and presence and uniqueness of `uid`
|
266
|
-
- Automatic generation of unique UID (32-character hex string) for each member
|
267
|
-
- Automatic population of `name` from `url` if name is not provided
|
268
|
-
- Navigation methods for finding next, previous, and random members:
|
269
|
-
- `find_next(source_member_uid)` - Finds the next member after the given UID
|
270
|
-
- `find_previous(source_member_uid)` - Finds the previous member before the given UID
|
271
|
-
- `find_random(source_member_uid: nil)` - Finds a random member, excluding the source member
|
272
|
-
|
273
|
-
#### Example Usage
|
274
|
-
|
275
|
-
```ruby
|
276
|
-
# Creating a new member
|
277
|
-
member = Webring::Member.create(url: "https://example.com", name: "Example Site")
|
278
|
-
|
279
|
-
# Finding the next member
|
280
|
-
next_member = Webring::Member.find_next(member.uid)
|
281
|
-
|
282
|
-
# Finding the previous member
|
283
|
-
prev_member = Webring::Member.find_previous(member.uid)
|
284
|
-
|
285
|
-
# Finding a random member (excluding the current one)
|
286
|
-
random_member = Webring::Member.find_random(source_member_uid: member.uid)
|
287
|
-
```
|
288
|
-
|
289
|
-
## Modules
|
290
|
-
|
291
|
-
### Webring::Navigation
|
292
|
-
|
293
|
-
> [!TIP]
|
294
|
-
> The Navigation module is designed to be highly extensible. You can easily override its methods to customize the navigation behavior for your specific needs.
|
295
|
-
|
296
|
-
The Navigation module provides methods for navigating through members in a webring pattern. It's designed to be extended by models that act as webring members.
|
297
|
-
|
298
|
-
#### Key Features
|
299
|
-
|
300
|
-
- **Webring-style navigation**: Implements the circular navigation pattern typical of webrings
|
301
|
-
- **UID-based member identification**: Uses unique identifiers instead of numeric IDs for security
|
302
|
-
- **Creation time ordering**: Uses `created_at` timestamps to determine the sequence of members
|
303
|
-
- **Edge case handling**: Properly handles wraparound at the beginning and end of the ring
|
304
|
-
|
305
|
-
#### Available Methods
|
306
|
-
|
307
|
-
The module provides three core methods:
|
308
|
-
|
309
|
-
- `find_next(source_member_uid)`: Finds the next member in the ring after the specified member
|
310
|
-
- If the source member is the last in the ring, it returns the first member
|
311
|
-
- Uses creation time for navigation ordering
|
312
|
-
|
313
|
-
- `find_previous(source_member_uid)`: Finds the previous member in the ring before the specified member
|
314
|
-
- If the source member is the first in the ring, it returns the last member
|
315
|
-
- Uses creation time for navigation ordering
|
316
|
-
|
317
|
-
- `find_random(source_member_uid: nil)`: Finds a random member in the ring
|
318
|
-
- If a source member UID is provided, it excludes that member from the selection
|
319
|
-
- If the source member is the only one in the ring, it returns that same member
|
320
|
-
|
321
|
-
#### Usage in Models
|
322
|
-
|
323
|
-
> [!WARNING]
|
324
|
-
> Make sure your model has `uid` and `created_at` columns before extending the Navigation module, as they're required for the default implementation.
|
325
|
-
|
326
|
-
The module is designed to be extended in your model:
|
327
|
-
|
328
|
-
```ruby
|
329
|
-
class YourMember < ApplicationRecord
|
330
|
-
extend Webring::Navigation
|
331
|
-
|
332
|
-
# Your model code...
|
333
|
-
end
|
334
|
-
```
|
335
|
-
|
336
|
-
#### Implementation Example
|
337
|
-
|
338
|
-
The `Webring::Member` model extends the Navigation module:
|
339
|
-
|
340
|
-
```ruby
|
341
|
-
module Webring
|
342
|
-
class Member < ApplicationRecord
|
343
|
-
extend Webring::Navigation
|
344
|
-
|
345
|
-
# Member model implementation...
|
346
|
-
end
|
347
|
-
end
|
348
|
-
```
|
349
|
-
|
350
|
-
This allows you to call navigation methods on the class:
|
351
|
-
|
352
|
-
```ruby
|
353
|
-
# Find the next member after member with UID 'abc123...'
|
354
|
-
next_member = Webring::Member.find_next('abc123...')
|
355
|
-
|
356
|
-
# Find the previous member before member with UID 'abc123...'
|
357
|
-
previous_member = Webring::Member.find_previous('abc123...')
|
358
|
-
|
359
|
-
# Find a random member (excluding member with UID 'abc123...')
|
360
|
-
random_member = Webring::Member.find_random(source_member_uid: 'abc123...')
|
361
|
-
```
|
362
|
-
|
363
|
-
#### Customizing Navigation Behavior
|
364
|
-
|
365
|
-
You can override the default navigation behavior by creating your own module that includes or extends the Webring::Navigation module:
|
366
|
-
|
367
|
-
```ruby
|
368
|
-
module YourApp
|
369
|
-
module CustomNavigation
|
370
|
-
include Webring::Navigation
|
371
|
-
|
372
|
-
# Override methods as needed
|
373
|
-
def find_next(source_member_uid)
|
374
|
-
# Custom implementation for finding the next member
|
375
|
-
# For example, you might want to order by name instead of created_at
|
376
|
-
source_member = find_by(uid: source_member_uid)
|
377
|
-
return order(:name).first unless source_member
|
378
|
-
|
379
|
-
where('name > ?', source_member.name)
|
380
|
-
.order(:name)
|
381
|
-
.first || order(:name).first
|
382
|
-
end
|
383
|
-
end
|
384
|
-
end
|
385
|
-
```
|
386
|
-
|
387
|
-
Then apply your custom navigation module to your model:
|
388
|
-
|
389
|
-
```ruby
|
390
|
-
class YourMember < ApplicationRecord
|
391
|
-
extend YourApp::CustomNavigation
|
392
|
-
|
393
|
-
# Your model code...
|
394
|
-
end
|
395
|
-
```
|
396
|
-
|
397
|
-
**Note**: The Navigation module requires models to have `uid` and `created_at` columns for its default implementation.
|
398
|
-
|
399
|
-
## Controllers
|
400
|
-
|
401
|
-
### Webring::NavigationController
|
402
|
-
|
403
|
-
> [!IMPORTANT]
|
404
|
-
> The Navigation controller is responsible for handling all webring navigation requests and redirecting users between member sites.
|
405
|
-
|
406
|
-
Navigation controller manages the webring navigation flow for end users visiting member sites:
|
407
|
-
|
408
|
-
- `next` - Redirects to the next member in the webring
|
409
|
-
- `previous` - Redirects to the previous member in the webring
|
410
|
-
- `random` - Redirects to a random member in the webring
|
411
|
-
|
412
|
-
This controller handles requests to navigate between members. When a navigation request is received with a source member's UID, the controller determines the appropriate member to navigate to and redirects the user to that member's URL.
|
413
|
-
|
414
|
-
#### How to Use the Navigation Controller
|
415
|
-
|
416
|
-
To use the navigation controller in your webring implementation, you need to create navigation links that point to your application's navigation routes with the `source_member_uid` parameter.
|
417
|
-
|
418
|
-
Example routes:
|
419
|
-
```
|
420
|
-
https://your-app.com/webring/previous?source_member_uid=abc123...
|
421
|
-
https://your-app.com/webring/random?source_member_uid=abc123...
|
422
|
-
https://your-app.com/webring/next?source_member_uid=abc123...
|
423
|
-
```
|
424
|
-
|
425
|
-
Replace `abc123...` with the actual member UID and `https://your-app.com` with your application's domain.
|
426
|
-
|
427
|
-
The controller handles several cases:
|
428
|
-
- If the source member UID is invalid or not found, it returns a 404 "Member not found" response
|
429
|
-
- If there are no members in the webring, it returns a 404 "No members in the webring" response
|
430
|
-
- For `next` and `previous` actions, if the current member is the last or first respectively, it wraps around to the other end of the ring
|
431
|
-
- For `random` action, it ensures the random member is not the same as the source member (unless there's only one member)
|
432
|
-
|
433
|
-
#### Customizing Navigation Behavior
|
434
|
-
|
435
|
-
If you want to customize the navigation behavior, you can create your own controller that inherits from the default navigation controller:
|
436
|
-
|
437
|
-
```ruby
|
438
|
-
# app/controllers/my_navigation_controller.rb
|
439
|
-
class MyNavigationController < Webring::NavigationController
|
440
|
-
# Override methods and call super if needed
|
441
|
-
def next
|
442
|
-
# Your custom logic before default behavior
|
443
|
-
super
|
444
|
-
# `super` will redirect to member.url, so no code will be executed after this
|
445
|
-
end
|
446
|
-
|
447
|
-
def previous
|
448
|
-
# Completely custom implementation
|
449
|
-
@previous_member = Webring::Member.find_previous(params[:source_member_uid])
|
450
|
-
redirect_to @previous_member.url, allow_other_host: true
|
451
|
-
end
|
452
|
-
end
|
453
|
-
```
|
454
|
-
|
455
|
-
Then update your routes to use your custom controller:
|
456
|
-
|
457
|
-
```ruby
|
458
|
-
# config/routes.rb
|
459
|
-
Rails.application.routes.draw do
|
460
|
-
# ... other routes ...
|
461
|
-
|
462
|
-
# Override default webring routes with your custom controller
|
463
|
-
get 'webring/next', to: 'my_navigation#next'
|
464
|
-
get 'webring/previous', to: 'my_navigation#previous'
|
465
|
-
get 'webring/random', to: 'my_navigation#random'
|
466
|
-
end
|
467
|
-
```
|
468
|
-
|
469
|
-
### Webring::MembersController
|
470
|
-
|
471
|
-
Members controller provides full CRUD functionality for managing webring members:
|
472
|
-
|
473
|
-
- `index` - Lists all webring members
|
474
|
-
- `show` - Displays details for a specific member
|
475
|
-
- `new` - Form for creating a new member
|
476
|
-
- `create` - Creates a new webring member
|
477
|
-
- `edit` - Form for editing an existing member
|
478
|
-
- `update` - Updates an existing webring member
|
479
|
-
- `destroy` - Deletes a webring member
|
480
|
-
|
481
|
-
This controller provides the basic functionality for your application to manage webring membership.
|
482
|
-
|
483
|
-
## Widget
|
484
|
-
|
485
|
-
### Webring::WidgetController
|
486
|
-
|
487
|
-
The Widget controller serves a JavaScript widget that can be embedded on member sites to provide navigation through the webring.
|
488
|
-
|
489
|
-
- `show` - Serves the widget.js JavaScript file with proper CORS headers
|
490
|
-
|
491
|
-
### Widget.js
|
492
|
-
|
493
|
-
The widget.js file is a standalone JavaScript snippet that creates a navigation widget on member sites. It's designed to be easily embedded with a single script tag and offers various customization options.
|
494
|
-
|
495
|
-
#### How to Use the Widget
|
496
|
-
|
497
|
-
To add the webring widget to a member's site, include the following code:
|
498
|
-
|
499
|
-
```html
|
500
|
-
<!-- Webring Widget -->
|
501
|
-
<script src='https://yourhub.com/webring/widget.js' data-member-uid='MEMBER_UID'></script>
|
502
|
-
<div id='webring-widget'></div>
|
503
|
-
<!-- End Webring Widget -->
|
504
|
-
```
|
505
|
-
|
506
|
-
Replace `https://yourhub.com` with your application's domain and `MEMBER_UID` with the member's unique identifier.
|
507
|
-
|
508
|
-
#### Widget Customization Options
|
509
|
-
|
510
|
-
The widget can be customized through data attributes on the script tag:
|
511
|
-
|
512
|
-
- **Widget Type** (`data-widget-type`):
|
513
|
-
- `full`: Text, back button, random button, forward button (default)
|
514
|
-
- `no-text`: Back button, random button, forward button (no text)
|
515
|
-
- `two-way`: Back and forward buttons (no random)
|
516
|
-
- `one-way`: Forward button only
|
517
|
-
|
518
|
-
- **Button Text** (`data-button-text`):
|
519
|
-
- `true`: Show text labels on buttons (default)
|
520
|
-
- `false`: Show only symbols (no text)
|
521
|
-
|
522
|
-
- **Styling** (`data-styles`):
|
523
|
-
- `full`: Apply all styles (default)
|
524
|
-
- `layout`: Only layout styles, no visual design
|
525
|
-
- `none`: No styles applied
|
526
|
-
|
527
|
-
- **Target Element** (`data-target-id`):
|
528
|
-
- Sets a custom ID for the target container (default: `webring-widget`)
|
529
|
-
|
530
|
-
#### Example With All Options
|
531
|
-
|
532
|
-
```html
|
533
|
-
<script src='https://yourhub.com/webring/widget.js'
|
534
|
-
data-member-uid='MEMBER_UID'
|
535
|
-
data-widget-type='full'
|
536
|
-
data-button-text='true'
|
537
|
-
data-styles='full'
|
538
|
-
data-target-id='custom-widget-id'></script>
|
539
|
-
<div id='custom-widget-id'></div>
|
540
|
-
```
|
541
|
-
|
542
|
-
#### Multiple Widgets on the Same Page
|
543
|
-
|
544
|
-
You can include multiple widgets on the same page by specifying different target IDs:
|
545
|
-
|
546
|
-
```html
|
547
|
-
<!-- First Widget -->
|
548
|
-
<script src='https://yourhub.com/webring/widget.js'
|
549
|
-
data-member-uid='MEMBER_UID'
|
550
|
-
data-widget-type='full'
|
551
|
-
data-target-id='webring-widget-1'></script>
|
552
|
-
<div id='webring-widget-1'></div>
|
553
|
-
|
554
|
-
<!-- Second Widget -->
|
555
|
-
<script src='https://yourhub.com/webring/widget.js'
|
556
|
-
data-member-uid='MEMBER_UID'
|
557
|
-
data-widget-type='no-text'
|
558
|
-
data-target-id='webring-widget-2'></script>
|
559
|
-
<div id='webring-widget-2'></div>
|
560
|
-
```
|
561
|
-
|
562
|
-
## Development
|
563
|
-
|
564
|
-
To set up the development environment:
|
565
|
-
|
566
|
-
1. Clone this repository
|
567
|
-
2. Run `bundle install`
|
568
|
-
3. Run `bin/setup_dummy` to prepare the test dummy app
|
569
|
-
|
570
|
-
### Migrations
|
571
|
-
|
572
|
-
After creating a new migration in the engine, you need to run:
|
573
|
-
```bash
|
574
|
-
cd test/dummy
|
575
|
-
bin/rails db:migrate
|
576
|
-
```
|
577
|
-
Which will run the migrations in the dummy app.
|
578
|
-
You don't need to copy migrations to the dummy app, it looks for them in the engine.
|
579
|
-
|
580
|
-
### Testing
|
581
|
-
|
582
|
-
> [!WARNING]
|
583
|
-
> As of now, there are no tests. Contributions to add test coverage are welcome!
|
584
|
-
|
585
|
-
## Contributing
|
586
|
-
|
587
|
-
We welcome contributions to Webring for Rails! Here's how you can help:
|
58
|
+
## Documentation
|
588
59
|
|
589
|
-
|
590
|
-
2. Create a feature branch: `git checkout -b my-new-feature`
|
591
|
-
3. Make your changes and add tests if possible
|
592
|
-
4. Commit your changes: `git commit -am 'Add some feature'`
|
593
|
-
5. Push to the branch: `git push origin my-new-feature`
|
594
|
-
6. Submit a pull request
|
60
|
+
For detailed documentation on models, controllers, modules, widget customization, and more advanced installation options, please visit the [Webring Rails Wiki](https://github.com/lstpsche/webring-rails/wiki).
|
595
61
|
|
596
62
|
## License
|
597
63
|
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module Webring
|
2
2
|
class MembersController < ::ApplicationController
|
3
|
-
before_action :
|
3
|
+
before_action :members, only: %i[index]
|
4
|
+
before_action :member, only: %i[show edit update destroy]
|
4
5
|
|
5
6
|
# GET /webring/members
|
6
|
-
def index
|
7
|
-
@members = Member.all.order(created_at: :desc)
|
8
|
-
end
|
7
|
+
def index; end
|
9
8
|
|
10
9
|
# GET /webring/members/1
|
11
10
|
def show; end
|
@@ -31,8 +30,8 @@ module Webring
|
|
31
30
|
|
32
31
|
# PATCH/PUT /webring/members/1
|
33
32
|
def update
|
34
|
-
if
|
35
|
-
redirect_to admin_panel_member_path(
|
33
|
+
if member.update(member_params)
|
34
|
+
redirect_to admin_panel_member_path(member), notice: 'Member was successfully updated.'
|
36
35
|
else
|
37
36
|
render :edit, status: :unprocessable_entity
|
38
37
|
end
|
@@ -40,21 +39,23 @@ module Webring
|
|
40
39
|
|
41
40
|
# DELETE /webring/members/1
|
42
41
|
def destroy
|
43
|
-
|
42
|
+
member.destroy
|
44
43
|
|
45
44
|
redirect_to admin_panel_members_url, notice: 'Member was successfully destroyed.'
|
46
45
|
end
|
47
46
|
|
48
47
|
private
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
def members
|
50
|
+
@members ||= Member.all.order(created_at: :desc)
|
51
|
+
end
|
52
|
+
|
53
|
+
def member
|
54
|
+
@member ||= Member.find_by!(uid: params[:id])
|
53
55
|
end
|
54
56
|
|
55
|
-
# Only allow a list of trusted parameters through.
|
56
57
|
def member_params
|
57
|
-
params.require(:member).permit(:name, :url)
|
58
|
+
params.require(:member).permit(:name, :url, :description)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Webring
|
2
|
+
class MembershipRequestsController < ApplicationController
|
3
|
+
def new
|
4
|
+
@membership_request = MembershipRequest.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
@membership_request = MembershipRequest.new(membership_request_params)
|
9
|
+
|
10
|
+
if @membership_request.save
|
11
|
+
redirect_to root_path
|
12
|
+
else
|
13
|
+
render :new, status: :unprocessable_entity
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def membership_request_params
|
20
|
+
params.require(:membership_request).permit(:name, :url, :callback_email, :description)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Webring
|
2
|
+
module MembershipRequestActions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def approve!
|
6
|
+
return if approved?
|
7
|
+
|
8
|
+
transaction do
|
9
|
+
update!(status: :approved)
|
10
|
+
|
11
|
+
Webring::Member.create!(
|
12
|
+
name: name,
|
13
|
+
url: url,
|
14
|
+
description: description,
|
15
|
+
webring_membership_request_id: id
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def reject!
|
21
|
+
return if rejected?
|
22
|
+
|
23
|
+
transaction do
|
24
|
+
update!(status: :rejected)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -5,11 +5,10 @@ module Webring
|
|
5
5
|
UID_LENGTH = 16 # 32-character hex string
|
6
6
|
|
7
7
|
validates :url, presence: true, uniqueness: true
|
8
|
-
validates :name,
|
8
|
+
validates :name, presence: true, uniqueness: true
|
9
9
|
validates :uid, presence: true, uniqueness: true, length: { is: UID_LENGTH * 2 }
|
10
10
|
|
11
11
|
before_validation :generate_uid, if: -> { uid.blank? }
|
12
|
-
before_validation :set_name_from_url, if: -> { name.blank? && url.present? }
|
13
12
|
|
14
13
|
def to_param
|
15
14
|
uid
|
@@ -23,9 +22,5 @@ module Webring
|
|
23
22
|
break unless self.class.exists?(uid: uid)
|
24
23
|
end
|
25
24
|
end
|
26
|
-
|
27
|
-
def set_name_from_url
|
28
|
-
self.name = url
|
29
|
-
end
|
30
25
|
end
|
31
26
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Webring
|
2
|
+
class MembershipRequest < ApplicationRecord
|
3
|
+
include Webring::MembershipRequestActions
|
4
|
+
|
5
|
+
has_one :member, class_name: 'Webring::Member',
|
6
|
+
foreign_key: :webring_membership_request_id,
|
7
|
+
dependent: :nullify,
|
8
|
+
inverse_of: :membership_request
|
9
|
+
|
10
|
+
validates :url, presence: true, uniqueness: true
|
11
|
+
validates :name, presence: true
|
12
|
+
validates :description, presence: true
|
13
|
+
|
14
|
+
enum :status, { pending: 0, approved: 1, rejected: 2 }, default: :pending
|
15
|
+
end
|
16
|
+
end
|
data/lib/generators/USAGE
CHANGED
@@ -6,8 +6,7 @@ Example:
|
|
6
6
|
rails generate webring:install
|
7
7
|
|
8
8
|
This will create:
|
9
|
-
|
10
|
-
# And mount the Webring engine in your routes.rb file
|
9
|
+
# Mount the Webring engine in your routes.rb file
|
11
10
|
|
12
11
|
Example:
|
13
12
|
rails generate webring:member
|
@@ -15,11 +14,25 @@ Example:
|
|
15
14
|
This will create:
|
16
15
|
app/models/webring/member.rb
|
17
16
|
db/migrate/TIMESTAMP_create_webring_members.rb
|
18
|
-
# And add member routes to your routes.rb file
|
19
17
|
|
20
18
|
Example:
|
21
|
-
rails generate webring:
|
19
|
+
rails generate webring:membership_request
|
20
|
+
|
21
|
+
This will create:
|
22
|
+
app/models/webring/membership_request.rb
|
23
|
+
db/migrate/TIMESTAMP_create_webring_membership_requests.rb
|
24
|
+
db/migrate/TIMESTAMP_add_membership_request_to_webring_members.rb
|
25
|
+
|
26
|
+
Example:
|
27
|
+
rails generate webring:navigation_controller
|
22
28
|
|
23
29
|
This will create:
|
24
30
|
app/controllers/webring/navigation_controller.rb
|
25
31
|
# And add navigation routes to your routes.rb file
|
32
|
+
|
33
|
+
Example:
|
34
|
+
rails generate webring:membership_requests_controller
|
35
|
+
|
36
|
+
This will create:
|
37
|
+
app/controllers/webring/membership_requests_controller.rb
|
38
|
+
# And add membership request routes to your routes.rb file
|
@@ -33,7 +33,26 @@ This will:
|
|
33
33
|
- GET /webring/previous - Navigate to the previous site
|
34
34
|
- GET /webring/random - Navigate to a random site
|
35
35
|
|
36
|
-
3.
|
36
|
+
3. Enable Membership Requests [Optional]
|
37
|
+
----------------------------------------
|
38
|
+
Generate a membership request model to allow sites to request joining your webring:
|
39
|
+
|
40
|
+
$ rails generate webring:membership_request
|
41
|
+
|
42
|
+
This will:
|
43
|
+
- Create a Webring::MembershipRequest model in app/models/webring/membership_request.rb
|
44
|
+
- Create migrations to set up the webring_membership_requests table
|
45
|
+
- Add appropriate database indexes and relations to Webring::Member
|
46
|
+
|
47
|
+
After generating the model, run the migration:
|
48
|
+
|
49
|
+
$ rails db:migrate
|
50
|
+
|
51
|
+
Then, optionally generate a controller to handle membership requests:
|
52
|
+
|
53
|
+
$ rails generate webring:controller:membership_requests
|
54
|
+
|
55
|
+
4. Customize Your Routes [Optional]
|
37
56
|
----------------------------------
|
38
57
|
The engine is mounted at '/webring' by default. You can change this in your routes.rb file:
|
39
58
|
|
@@ -43,7 +62,7 @@ The engine is mounted at '/webring' by default. You can change this in your rout
|
|
43
62
|
# Example custom mount point
|
44
63
|
mount Webring::Engine => '/network', as: 'webring'
|
45
64
|
|
46
|
-
|
65
|
+
5. Add Webring Navigation UI Elements
|
47
66
|
------------------------------------
|
48
67
|
Add navigation links to your views to enable users to navigate through the webring:
|
49
68
|
|
@@ -54,7 +73,7 @@ Add navigation links to your views to enable users to navigate through the webri
|
|
54
73
|
Note: Replace 'your_member.uid' with the actual UID of your site in the webring.
|
55
74
|
If you're building a standalone webring hub, you can omit the source_member_uid parameter.
|
56
75
|
|
57
|
-
|
76
|
+
6. Managing Webring Members
|
58
77
|
--------------------------
|
59
78
|
You can add members to your webring using the Webring::Member model:
|
60
79
|
|
@@ -13,6 +13,7 @@ module Webring
|
|
13
13
|
# # uid - A unique identifier for the member (automatically generated)
|
14
14
|
# # name - The name of the member site (defaults to URL if not provided)
|
15
15
|
# # url - The URL of the member site (required)
|
16
|
+
# # description - The description of the member site (required)
|
16
17
|
#
|
17
18
|
# @note After running this generator, you should run the migration with:
|
18
19
|
# rails db:migrate
|
@@ -18,21 +18,14 @@ The generated model is located at:
|
|
18
18
|
|
19
19
|
The Member model has the following attributes:
|
20
20
|
- uid: A unique identifier automatically generated for each member (32-character hex)
|
21
|
-
- name: The name of the member site (
|
21
|
+
- name: The name of the member site (required)
|
22
22
|
- url: The URL of the member site (required)
|
23
|
+
- description: The description of the member site (required)
|
23
24
|
|
24
25
|
3. Adding Members to Your Webring
|
25
26
|
-------------------------------
|
26
27
|
You can add members to your webring using the Webring::Member model:
|
27
28
|
|
28
|
-
Webring::Member.create(name: 'Example Site', url: 'https://example.com')
|
29
|
+
Webring::Member.create(name: 'Example Site', url: 'https://example.com', description: 'Example description')
|
29
30
|
|
30
|
-
The uid will be automatically generated if not provided.
|
31
|
-
|
32
|
-
4. Next Steps
|
33
|
-
-----------
|
34
|
-
Consider generating the navigation controller to enable navigation between webring members:
|
35
|
-
|
36
|
-
$ rails generate webring:controller
|
37
|
-
|
38
|
-
This will create routes and controller actions for webring navigation.
|
31
|
+
The uid will be automatically generated if not provided. It is recommended to leave the UID generation to the model.
|
@@ -2,14 +2,15 @@ class CreateWebringMembers < ActiveRecord::Migration<%= "[#{Rails::VERSION::MAJO
|
|
2
2
|
def change
|
3
3
|
create_table :webring_members do |t|
|
4
4
|
t.string :uid, null: false, limit: 32
|
5
|
-
t.string :name
|
5
|
+
t.string :name, null: false
|
6
6
|
t.string :url, null: false
|
7
|
+
t.text :description, null: false
|
8
|
+
|
9
|
+
t.index :uid, unique: true
|
10
|
+
t.index :name, unique: true
|
11
|
+
t.index :url, unique: true
|
7
12
|
|
8
13
|
t.timestamps
|
9
14
|
end
|
10
|
-
|
11
|
-
add_index :webring_members, :uid, unique: true
|
12
|
-
add_index :webring_members, :name, unique: true
|
13
|
-
add_index :webring_members, :url, unique: true
|
14
15
|
end
|
15
16
|
end
|
@@ -5,11 +5,10 @@ module Webring
|
|
5
5
|
UID_LENGTH = 16 # 32-character hex string
|
6
6
|
|
7
7
|
validates :url, presence: true, uniqueness: true
|
8
|
-
validates :name,
|
8
|
+
validates :name, presence: true, uniqueness: true
|
9
9
|
validates :uid, presence: true, uniqueness: true, length: { is: UID_LENGTH * 2 }
|
10
10
|
|
11
11
|
before_validation :generate_uid, if: -> { uid.blank? }
|
12
|
-
before_validation :set_name_from_url, if: -> { name.blank? && url.present? }
|
13
12
|
|
14
13
|
def to_param
|
15
14
|
uid
|
@@ -23,9 +22,5 @@ module Webring
|
|
23
22
|
break unless self.class.exists?(uid: uid)
|
24
23
|
end
|
25
24
|
end
|
26
|
-
|
27
|
-
def set_name_from_url
|
28
|
-
self.name = url
|
29
|
-
end
|
30
25
|
end
|
31
26
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
require 'rails/generators/named_base'
|
3
|
+
require_relative '../shared/route_injector'
|
4
|
+
|
5
|
+
module Webring
|
6
|
+
module Generators
|
7
|
+
# @description The MembershipRequestGenerator creates the MembershipRequest model for handling webring membership requests
|
8
|
+
# It creates both the model file and a migration to create the database table
|
9
|
+
#
|
10
|
+
# @usage Run: rails generate webring:membership_request
|
11
|
+
#
|
12
|
+
# @example Generated MembershipRequest model has the following attributes:
|
13
|
+
# # name - The name of the member site
|
14
|
+
# # url - The URL of the member site (required)
|
15
|
+
# # callback_email - Email for notifications
|
16
|
+
# # description - Description of the site
|
17
|
+
#
|
18
|
+
# @note After running this generator, you should run the migration with:
|
19
|
+
# rails db:migrate
|
20
|
+
class MembershipRequestGenerator < Rails::Generators::Base
|
21
|
+
include Rails::Generators::Migration
|
22
|
+
include Shared::RouteInjector
|
23
|
+
|
24
|
+
source_root File.expand_path('templates', __dir__)
|
25
|
+
|
26
|
+
desc 'Creates a Webring::MembershipRequest model and necessary migration for storing webring membership requests'
|
27
|
+
|
28
|
+
# Creates a migration file to create the webring_membership_requests table
|
29
|
+
# @return [void]
|
30
|
+
def create_migration_file
|
31
|
+
migration_template 'migration.rb', 'db/migrate/create_webring_membership_requests.rb'
|
32
|
+
migration_template 'relations_migration.rb', 'db/migrate/add_membership_request_to_webring_members.rb'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates the MembershipRequest model file based on the template
|
36
|
+
# @return [void]
|
37
|
+
def create_model_file
|
38
|
+
template 'model.rb', 'app/models/webring/membership_request.rb'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Injects the belongs_to relationship into the Member model
|
42
|
+
# @return [void]
|
43
|
+
def inject_into_member_model
|
44
|
+
member_model_path = 'app/models/webring/member.rb'
|
45
|
+
|
46
|
+
if File.exist?(member_model_path)
|
47
|
+
inject_into_file member_model_path, after: "class Member\n" do
|
48
|
+
" belongs_to :membership_request,\n" \
|
49
|
+
" class_name: 'Webring::MembershipRequest',\n" \
|
50
|
+
" foreign_key: :webring_membership_request_id,\n" \
|
51
|
+
" optional: true,\n" \
|
52
|
+
" inverse_of: :member\n"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Generates the next migration number for the migration file
|
58
|
+
# This is required by Rails::Generators::Migration
|
59
|
+
# @param dirname [String] The directory where migrations are stored
|
60
|
+
# @return [Integer] The next migration number
|
61
|
+
def self.next_migration_number(dirname)
|
62
|
+
next_migration_number = current_migration_number(dirname) + 1
|
63
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Displays the README with next steps after installation
|
67
|
+
# @return [void]
|
68
|
+
def show_readme
|
69
|
+
readme 'AFTER_INSTALL' if behavior == :invoke
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
==============================================
|
2
|
+
Webring::MembershipRequest Model Has Been Generated!
|
3
|
+
==============================================
|
4
|
+
|
5
|
+
The MembershipRequest model is the core component for handling new site requests to join your webring. Follow these steps to complete the setup:
|
6
|
+
|
7
|
+
1. Run Database Migration
|
8
|
+
------------------------
|
9
|
+
Apply the migration to create the webring_membership_requests table:
|
10
|
+
|
11
|
+
$ rails db:migrate
|
12
|
+
|
13
|
+
2. Review and Customize the Model
|
14
|
+
-------------------------------
|
15
|
+
The generated model is located at:
|
16
|
+
app/models/webring/membership_request.rb
|
17
|
+
|
18
|
+
The MembershipRequest model has the following attributes:
|
19
|
+
- name: The name of the requesting site (required)
|
20
|
+
- url: The URL of the requesting site (required)
|
21
|
+
- callback_email: The email address to send notifications to (required)
|
22
|
+
- description: The description of the requesting site (required)
|
23
|
+
- status: The status of the request (pending, approved, rejected)
|
24
|
+
|
25
|
+
3. Generate Controller [Optional]
|
26
|
+
--------------------------------
|
27
|
+
Generate a controller to handle membership requests:
|
28
|
+
|
29
|
+
$ rails generate webring:controller:membership_requests
|
30
|
+
|
31
|
+
This will:
|
32
|
+
- Create the Webring::MembershipRequestsController in app/controllers/webring/membership_requests_controller.rb
|
33
|
+
- Add membership request routes to your routes.rb file:
|
34
|
+
- GET /webring/membership_requests/new - Renders the view for submitting a new membership request (view is your responsibility)
|
35
|
+
- POST /webring/membership_requests - Creates a new membership request
|
36
|
+
|
37
|
+
4. Managing Membership Requests
|
38
|
+
-------------------------------
|
39
|
+
You can manage membership requests using the Webring::MembershipRequest model:
|
40
|
+
|
41
|
+
Webring::MembershipRequest.create(name: 'Example Site', url: 'https://example.com', description: 'Example description', callback_email: 'example@example.com')
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateWebringMembershipRequests < ActiveRecord::Migration<%= "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" %>
|
2
|
+
def change
|
3
|
+
create_table :webring_membership_requests do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.string :url, null: false
|
6
|
+
t.text :description, null: false
|
7
|
+
t.string :callback_email, null: false
|
8
|
+
t.integer :status, default: 0
|
9
|
+
|
10
|
+
t.index :url, unique: true
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Webring
|
2
|
+
class MembershipRequest < ApplicationRecord
|
3
|
+
has_one :member, class_name: 'Webring::Member',
|
4
|
+
foreign_key: :webring_membership_request_id,
|
5
|
+
dependent: :nullify,
|
6
|
+
inverse_of: :membership_request
|
7
|
+
|
8
|
+
validates :url, presence: true, uniqueness: true
|
9
|
+
validates :name, presence: true
|
10
|
+
validates :description, presence: true
|
11
|
+
|
12
|
+
enum :status, { pending: 0, approved: 1, rejected: 2 }, default: :pending
|
13
|
+
|
14
|
+
def approve!
|
15
|
+
return if approved?
|
16
|
+
|
17
|
+
transaction do
|
18
|
+
update!(status: :approved)
|
19
|
+
|
20
|
+
Webring::Member.create!(
|
21
|
+
name: name,
|
22
|
+
url: url,
|
23
|
+
description: description,
|
24
|
+
webring_membership_request_id: id
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../shared/route_injector'
|
2
|
+
|
3
|
+
module Webring
|
4
|
+
module Generators
|
5
|
+
# @description The MembershipRequestsControllerGenerator creates a controller to handle webring membership requests
|
6
|
+
# This generator creates both the controller file and adds the required routes
|
7
|
+
#
|
8
|
+
# @usage Run: rails generate webring:controller:membership_requests
|
9
|
+
#
|
10
|
+
# @example The generated controller provides endpoints for creating membership requests:
|
11
|
+
# # GET /webring/membership_requests/new - Controller for creating a new membership request
|
12
|
+
# # POST /webring/membership_requests - Create a new membership request
|
13
|
+
#
|
14
|
+
# @note This generator should be run after installing the Webring engine and
|
15
|
+
# generating the MembershipRequest model with webring:membership_request
|
16
|
+
class MembershipRequestsControllerGenerator < Rails::Generators::Base
|
17
|
+
include Shared::RouteInjector
|
18
|
+
|
19
|
+
source_root File.expand_path('templates', __dir__)
|
20
|
+
|
21
|
+
desc 'Creates a Webring::MembershipRequestsController and necessary routes for membership requests'
|
22
|
+
|
23
|
+
# Creates the MembershipRequestsController file based on the template
|
24
|
+
# @return [void]
|
25
|
+
def create_controller_file
|
26
|
+
template 'membership_requests_controller.rb', 'app/controllers/webring/membership_requests_controller.rb'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds membership request routes to the application's routes.rb file
|
30
|
+
# These routes are used to create new membership requests
|
31
|
+
# @return [void]
|
32
|
+
def create_membership_request_routes
|
33
|
+
route_content = <<~ROUTE
|
34
|
+
# Webring membership request routes
|
35
|
+
namespace :webring do
|
36
|
+
resources :membership_requests, only: [:new, :create]
|
37
|
+
end
|
38
|
+
ROUTE
|
39
|
+
|
40
|
+
inject_webring_routes(route_content)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Webring
|
2
|
+
class MembershipRequestsController < ApplicationController
|
3
|
+
def new
|
4
|
+
@membership_request = MembershipRequest.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
@membership_request = MembershipRequest.new(membership_request_params)
|
9
|
+
|
10
|
+
if @membership_request.save
|
11
|
+
redirect_to root_path, notice: 'Your membership request has been submitted!'
|
12
|
+
else
|
13
|
+
render :new, status: :unprocessable_entity
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def membership_request_params
|
20
|
+
params.require(:membership_request).permit(:name, :url, :callback_email, :description)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -14,7 +14,7 @@ module Webring
|
|
14
14
|
#
|
15
15
|
# @note This generator should be run after installing the Webring engine and
|
16
16
|
# generating the Member model with webring:member
|
17
|
-
class
|
17
|
+
class NavigationControllerGenerator < Rails::Generators::Base
|
18
18
|
include Shared::RouteInjector
|
19
19
|
|
20
20
|
source_root File.expand_path('templates', __dir__)
|
data/lib/webring/version.rb
CHANGED
data/lib/webring-rails.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webring-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Shkoda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -65,22 +65,32 @@ files:
|
|
65
65
|
- app/assets/javascripts/webring/widget.js
|
66
66
|
- app/controllers/webring/application_controller.rb
|
67
67
|
- app/controllers/webring/members_controller.rb
|
68
|
+
- app/controllers/webring/membership_requests_controller.rb
|
68
69
|
- app/controllers/webring/navigation_controller.rb
|
69
70
|
- app/controllers/webring/widget_controller.rb
|
70
71
|
- app/helpers/webring/application_helper.rb
|
72
|
+
- app/models/concerns/webring/membership_request_actions.rb
|
71
73
|
- app/models/concerns/webring/navigation.rb
|
72
74
|
- app/models/webring/application_record.rb
|
73
75
|
- app/models/webring/member.rb
|
76
|
+
- app/models/webring/membership_request.rb
|
74
77
|
- config/routes.rb
|
75
78
|
- lib/generators/USAGE
|
76
|
-
- lib/generators/webring/controller/controller_generator.rb
|
77
|
-
- lib/generators/webring/controller/templates/navigation_controller.rb
|
78
79
|
- lib/generators/webring/install/install_generator.rb
|
79
80
|
- lib/generators/webring/install/templates/AFTER_INSTALL
|
80
81
|
- lib/generators/webring/member/member_generator.rb
|
81
82
|
- lib/generators/webring/member/templates/AFTER_INSTALL
|
82
83
|
- lib/generators/webring/member/templates/migration.rb
|
83
84
|
- lib/generators/webring/member/templates/model.rb
|
85
|
+
- lib/generators/webring/membership_request/membership_request_generator.rb
|
86
|
+
- lib/generators/webring/membership_request/templates/AFTER_INSTALL
|
87
|
+
- lib/generators/webring/membership_request/templates/migration.rb
|
88
|
+
- lib/generators/webring/membership_request/templates/model.rb
|
89
|
+
- lib/generators/webring/membership_request/templates/relations_migration.rb
|
90
|
+
- lib/generators/webring/membership_requests_controller/membership_requests_controller_generator.rb
|
91
|
+
- lib/generators/webring/membership_requests_controller/templates/membership_requests_controller.rb
|
92
|
+
- lib/generators/webring/navigation_controller/navigation_controller_generator.rb
|
93
|
+
- lib/generators/webring/navigation_controller/templates/navigation_controller.rb
|
84
94
|
- lib/generators/webring/shared/route_injector.rb
|
85
95
|
- lib/generators/webring_generator.rb
|
86
96
|
- lib/webring-rails.rb
|
/data/lib/generators/webring/{controller → navigation_controller}/templates/navigation_controller.rb
RENAMED
File without changes
|