Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 76 additions & 14 deletions docs/featury/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
---
title: Getting started with Featury
description: Requirements, conventions, installation and example of basic preparation
title: Getting Started with Featury
description: Guide to installing and configuring Featury
prev: false
next: false
---

# Getting started with Featury
# Getting Started with Featury

## Conventions
## What is Featury?

- All feature classes are subclasses of `Featury::Base` and are located in the `app/features` directory. It is common practice to create and inherit from `FeatureService::Base` class, which is a subclass of `Featury::Base`.
- Name features based on the process they relate to. Use nouns in names and try to equate them with model names whenever possible. For example, name the feature class `User::OnboardingFeature` instead of `User::OnboardFeature`.
Featury is a library for managing feature flags in Ruby/Rails applications. It provides a convenient API for working with feature flags and their groups.

## Version support
## Development Conventions

Featury follows certain conventions to ensure code consistency:

- All feature classes must inherit from `Featury::Base` and be placed in the `app/features` directory
- It is recommended to create a base class `ApplicationFeature::Base` that inherits from `Featury::Base`
- Feature names should reflect their belonging to the process
- Use nouns in feature names (e.g., `User::OnboardingFeature` instead of `User::OnboardFeature`)

## Version Support

Featury supports the following Ruby and Rails versions:

| Ruby/Rails | 8.0 | 7.2 | 7.1 | 7.0 | 6.1 | 6.0 | 5.2 | 5.1 | 5.0 |
|-------------|---|---|---|---|---|---|---|---|---|
Expand All @@ -24,33 +34,40 @@ next: false

## Installation

Add this to `Gemfile`:
### Adding the Gem

Add Featury to your `Gemfile`:

```ruby
gem "featury"
```

And execute:
### Installing Dependencies

Run the command to install the gem:

```shell
bundle install
```

## Preparation
## Environment Setup

As a first step, it is recommended to prepare the base class for further inheritance.
This base class should contain actions within itself with the integration of the tool for features in the project.
### Creating a Base Class

To start, it is recommended to prepare a base class for further inheritance.
This base class should contain actions with integration of the feature tool in the project.
For example, it could be an ActiveRecord model, Flipper, or something else.

### ActiveRecord model
### Example with ActiveRecord

The `FeatureFlag` model will be used as an example.
The `FeatureFlag` model will be used as an example:

::: code-group

```ruby [app/features/application_feature/base.rb]
module ApplicationFeature
class Base < Featury::Base
# Check if feature is enabled
action :enabled? do |features:, **options|
features.all? do |feature|
FeatureFlag
Expand All @@ -59,6 +76,7 @@ module ApplicationFeature
end
end

# Check if feature is disabled
action :disabled? do |features:, **options|
features.any? do |feature|
!FeatureFlag
Expand All @@ -67,6 +85,7 @@ module ApplicationFeature
end
end

# Enable feature
action :enable do |features:, **options|
features.all? do |feature|
FeatureFlag
Expand All @@ -75,6 +94,7 @@ module ApplicationFeature
end
end

# Disable feature
action :disable do |features:, **options|
features.all? do |feature|
FeatureFlag
Expand All @@ -83,10 +103,12 @@ module ApplicationFeature
end
end

# Hook before executing any action
before do |action:, features:|
Slack::API::Notify.call!(action:, features:)
end

# Hook after executing enabled? and disabled? actions
after :enabled?, :disabled? do |action:, features:|
Slack::API::Notify.call!(action:, features:)
end
Expand All @@ -95,3 +117,43 @@ end
```

:::

## Creating the First Feature

### Feature Example

```ruby
class User::OnboardingFeature < ApplicationFeature::Base
# Prefix for feature flags
prefix :onboarding

# User resource
resource :user, type: User

# Condition for working with the feature
condition ->(resources:) { resources.user.onboarding_awaiting? }

# Set of feature flags
features :passage, :integration

# Groups of feature flags
groups BillingFeature,
PaymentSystemFeature
end
```

### Usage

```ruby
# Check if feature is enabled
User::OnboardingFeature.enabled?(user: current_user)

# Enable feature
User::OnboardingFeature.enable(user: current_user)

# Check if feature is disabled
User::OnboardingFeature.disabled?(user: current_user)

# Disable feature
User::OnboardingFeature.disable(user: current_user)
```
12 changes: 6 additions & 6 deletions docs/featury/guide/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ prev: false
next: false
---

# Actions of Featury
# Featury Actions

To work with feature flags via Featury, need to create actions.
Each action involves implementing logic over the names of the received feature flags and additional options.
To work with feature flags via Featury, you need to create actions.
Each action involves implementing logic for the names of the received feature flags and additional options.

## Example

As an example, let's imagine that we have an ActiveRecord model that is responsible for all the project's feature flags.
It's called `FeatureFlag`.
As an example, let's imagine we have an ActiveRecord model responsible for all feature flags in the project.
It is called `FeatureFlag`.

Let's also imagine that working with feature flags in a project requires 4 actions:
Also, let's assume that the project requires 4 actions to work with feature flags:

- `enabled?`
- `disabled?`
Expand Down
4 changes: 2 additions & 2 deletions docs/featury/guide/callbacks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Callbacks of the Featury object
description: Description and examples of using callbacks of the Featury object
title: Featury Object Callbacks
description: Description and examples of using Featury object callbacks
prev: false
next: false
---
Expand Down
2 changes: 1 addition & 1 deletion docs/featury/guide/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ class User::OnboardingFeature < ApplicationFeature

features :passage # [!code focus]
end

```

```ruby [Several]
Expand Down Expand Up @@ -143,3 +142,4 @@ class User::OnboardingFeature < ApplicationFeature
groups BillingFeature, # [!code focus]
PaymentSystemFeature # [!code focus]
end
```
14 changes: 8 additions & 6 deletions docs/featury/guide/info.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
---
title: Information about Featury object
description: Description and examples of using the method to obtain information about a Featury object
title: Featury Object Information
description: Description and examples of getting information about features in Featury
prev: false
next: false
---

# Information about Featury object
# Featury Object Information

Information can be obtained about each Featury object.
Featury provides methods for getting information about features and their structure. This can be useful for debugging, documentation, and validation.

## Method `info`
## `info` method

The `info` method returns detailed information about a feature, including all feature flags and groups.

```ruby [Example]
info = User::OnboardingFeature.info
Expand All @@ -18,5 +20,5 @@ info = User::OnboardingFeature.info
```ruby
info.features # Feature flags of the current class.
info.groups # Feature flag groups of the current class.
info.tree # Tree of feature flags from the current class.
info.tree # Feature flag tree from the current class.
```
24 changes: 12 additions & 12 deletions docs/guide/actions/grouping.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
title: Grouping actions in service
description: Description and examples of grouping actions (methods) in service
prev: Options for actions in service
next: Early successful termination
title: Grouping Actions in a Service
description: Description and examples of grouping actions (methods) in a service
prev: Options for Actions in a Service
next: Early Successful Completion
---

# Grouping actions
# Grouping Actions

You can use the `stage` method to group multiple methods into one execution group.
You can group the execution of several methods using the `stage` method.

:::info
::: info

Usage of the `position` option for `make` will sort only in `stage`.
Using the `position` option for `make` will only sort within `stage`.

:::

Expand Down Expand Up @@ -39,6 +39,8 @@ end

### Option `only_unless`

The opposite of the `only_if` option.

```ruby {2}
stage do
only_unless ->(context:) { Settings.features.preview.disabled }
Expand All @@ -49,11 +51,9 @@ stage do
end
```

The opposite of the `only_if` option.

### Option `wrap_in`

Group of methods in `stage` can be wrapped in something.
The group of methods in `stage` can be wrapped in something.
For example, it could be `ActiveRecord::Base.transaction` from Rails.

```ruby {2}
Expand All @@ -68,7 +68,7 @@ end

### Option `rollback`

If an exception occurs in one of the methods in the group or in `wrap_in`, this can be handled using the `rollback` method.
If an exception occurs in one of the methods in the group or in `wrap_in`, it can be handled using the `rollback` method.

```ruby {3,12}
stage do
Expand Down
42 changes: 21 additions & 21 deletions docs/guide/actions/usage.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
---
title: Using actions in service
description: Description and examples of using actions (methods) in the service
prev: Dynamic options
next: Options for actions in service
title: Using Actions in a Service
description: Description and examples of using actions (methods) in a service
prev: Dynamic Options
next: Options for Actions in a Service
---

# Using actions
# Using Actions

Actions in the service are sequential calls to methods.
Actions in a service are sequential method calls.
Service methods are called using the `make` method.

## Examples

### Minimal

In its minimal form, calling methods via `make` is optional.
The `call` method can be used instead.
In its minimal form, calling methods through `make` is optional.
Instead, you can use the `call` method.

```ruby
class PostsService::Create < ApplicationService::Base
Expand All @@ -25,7 +25,7 @@ class PostsService::Create < ApplicationService::Base
end
```

### Several methods
### Multiple Methods

```ruby{4-6,8,12,16}
class PostsService::Create < ApplicationService::Base
Expand All @@ -51,15 +51,15 @@ end

## Options

You can find out more about options in the [options](../actions/options) section.
For more information about options, see the [options](../actions/options) section.

## Group of multiple actions
## Group of Multiple Actions

You can find out more about a group of multiple actions (methods) in the [grouping](../actions/grouping) section.
For more information about a group of multiple actions (methods), see the [grouping](../actions/grouping) section.

## Aliases for `make`

Through the `action_aliases` configuration it is possible to add alternatives to the `make` method.
You can add alternative options for the `make` method through the `action_aliases` configuration.

```ruby {2,5}
configuration do
Expand All @@ -75,10 +75,10 @@ end

## Customization for `make`

Add frequently used words that are used as prefixes in method names through the `action_shortcuts` configuration.
It won't make the names of methods shorter, but that will shorten the lines using the `make` method and improve the readability of the service code, making it more expressive.
Through the `action_shortcuts` configuration, you can add frequently used words that are used as prefixes in method names.
The method names themselves won't become shorter, but this will allow you to shorten the lines with the `make` method and improve the readability of the service code, making it more expressive.

### Simple mode
### Simple Mode

In simple mode, values are passed as an array of symbols.

Expand Down Expand Up @@ -110,18 +110,18 @@ class CMSService::API::Posts::Create < CMSService::API::Base
end
```

### Advanced mode <Badge type="tip" text="Since 2.14.0" />
### Extended Mode <Badge type="tip" text="Since 2.14.0" />

In advanced mode, values are passed as a hash.
In extended mode, values are passed as a hash.

```ruby
configuration do
action_shortcuts(
%i[assign],
{
restrict: { # replacement for make
prefix: :create, # method name prefix
suffix: :restriction # method name suffix
restrict: { # replacement for make
prefix: :create, # method name prefix
suffix: :restriction # method name suffix
}
}
)
Expand Down
Loading