Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refine documentation. Part 2 #103

Merged
merged 2 commits into from
Apr 5, 2023
Merged
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
40 changes: 27 additions & 13 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ end
```

There are several ways to execute a recently defined business action, including `#perform`, `#perform!`, or `try_perform!`:

1. `perform!` raises an exception when encountering errors.
1. `perform` returns `false` when encountering errors.
1. `try_perform!` is comparable to `perform!` but doesn't execute the action if preconditions are not met.

2. `perform` returns `false` when encountering errors.

3. `try_perform!` is comparable to `perform!` but doesn't execute the action if preconditions are not met.

### Transactions

Expand Down Expand Up @@ -188,7 +191,7 @@ The behavior of the attributes is similar to that of `Granite::Form` objects, wi

With Granite Form objects, when a model attribute is exposed via `represents` and the Active Record object changes, the exposed attribute is immediately updated.

_In contrast_, Granite Actions use `assign_data` to update the represented attribute.
_In contrast_, Granite actions use `assign_data` to update the represented attribute.

#### Assigning the data

Expand Down Expand Up @@ -247,9 +250,12 @@ validates :subaction, nested: true
### Subject

The definition of the subject does three things:

1. Defines a `references_one` association.
1. Aliases its methods to common names (`subject` and `subject_id`)
1. Modifies the action initializer to provide the ability to pass the subject as the first argument and restricts subject-less action initialization.

2. Aliases its methods to common names (`subject` and `subject_id`)

3. Modifies the action initializer to provide the ability to pass the subject as the first argument and restricts subject-less action initialization.

Let's take a look to an example below:

Expand Down Expand Up @@ -289,9 +295,12 @@ Notice that the method `#user` has been assigned to the alias `#subject`, and `#
### Policies, preconditions, and validations

When deciding how to structure policies, preconditions, and validations, there are some simple rules to follow:

1. If the condition depends on _any user-provided attribute values_ except for the subject, it is a **validation**.
1. If the condition depends on _the subject or any value that depends on the subject_, it is a **precondition**.
1. Otherwise, if it is _related to the performer_, choose a **policy**.

2. If the condition depends on _the subject or any value that depends on the subject_, it is a **precondition**.

3. Otherwise, if it is _related to the performer_, choose a **policy**.

#### Policies

Expand All @@ -309,9 +318,12 @@ end
There is also an `allow_self` method that is equivalent to `allow_if { performer == subject }`, which allows an action to be performed by the subject itself.

Granite policies also support strategies:

1. By default, the [`AnyStrategy`](https://github.com/toptal/granite/blob/master/lib/granite/action/policies/any_strategy.rb) is used, which allows an action to be performed if any policy allows it.
1. Other built-in strategies include [`AlwaysAllowStrategy`](https://github.com/toptal/granite/blob/master/lib/granite/action/policies/always_allow_strategy.rb), which allows all actions,
1. And [`RequiredPerformerStrategy`](https://github.com/toptal/granite/blob/master/lib/granite/action/policies/required_performer_strategy.rb), which requires that a performer be present for all actions.

2. Other built-in strategies include [`AlwaysAllowStrategy`](https://github.com/toptal/granite/blob/master/lib/granite/action/policies/always_allow_strategy.rb), which allows all actions,

3. And [`RequiredPerformerStrategy`](https://github.com/toptal/granite/blob/master/lib/granite/action/policies/required_performer_strategy.rb), which requires that a performer be present for all actions.

You can also write your own custom policy strategy.

Expand Down Expand Up @@ -469,11 +481,13 @@ Here are some examples of using the rails g granite command:

This command generates a new action called "create" for the "user" `subject`. It creates three files: `apq/actions/ba/user/create.rb`, `apq/actions/ba/user/business_action.rb`, and `spec/apq/actions/ba/user/create_spec.rb`.

1. `rails g granite user/create -C`
Adding the `-C` option generates a collection action where the subject is not known at initialization. This command generates two files: `apq/actions/ba/user/create.rb` and `spec/apq/actions/ba/user/create_spec.rb`.
2. `rails g granite user/create -C`

Adding the `-C` option generates a collection action where the subject is not known at initialization. This command generates two files: `apq/actions/ba/user/create.rb` and `spec/apq/actions/ba/user/create_spec.rb`.

3. `rails g granite user/create simple`

1. `rails g granite user/create simple`
Adding a second argument, such as "simple" specifies the name of the projector to use. This command generates a new directory called simple within the `apq/actions/ba/user/create directory`, as well as the same files as the first example: `apq/actions/ba/user/create.rb`, `apq/actions/ba/user/business_action.rb`, and `spec/apq/actions/ba/user/create_spec.rb`.
Adding a second argument, such as "simple" specifies the name of the projector to use. This command generates a new directory called simple within the `apq/actions/ba/user/create directory`, as well as the same files as the first example: `apq/actions/ba/user/create.rb`, `apq/actions/ba/user/business_action.rb`, and `spec/apq/actions/ba/user/create_spec.rb`.

## Conclusion

Expand Down
Loading