Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • C chouette-core
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 36
    • Merge requests 36
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Infrastructure Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Administrator
  • chouette-core
  • Wiki
  • Rails views

Rails views · Changes

Page history
Retrieve chouette-core wiki content authored May 06, 2018 by Alban Peignier's avatar Alban Peignier
Show whitespace changes
Inline Side-by-side
Showing with 166 additions and 0 deletions
+166 -0
  • Rails-views.md Rails-views.md +166 -0
  • No files found.
Rails-views.md 0 → 100644
View page @ f9aa7ef7
## Decorators
### Usage
We define only a single decorator per model that must inherit from `AF83::Decorator`. This model decorator handles both collections and instances. To decorate an `Item` object:
```ruby
# app/controllers/items_controller.rb
def index
# ...
@items = ItemDecorator.decorate(@items)
# ...
end
def show
# ...
@item = @item.decorate
# ...
end
```
The actions on the **collection** are defined at the root of the decorator, while those for instances are defined with the help of a `with_instance_decorator` block.
To define an action, we use the `action_link` method. The method accepts these options:
- `on`: only shows the link on the pages for the listed actions (e.g. `on: %i(show index)`)
- `if`: takes a `Proc` and only displays the link if the proc result is _truthy_
- `policy`: only shows the link if the current user has the permission for the decorated object and action link (takes an action argument, for example `:edit`, or `:create`)
- `feature`: like `policy`, but for a `feature`
- `weight`: allow the links' display order to be changed, with `weight: 1` shown first (by default, the declaration order is used)
Actions are also split into **groups**. These can be customised in several ways:
```ruby
groups: {
primary: true,
secondary: %i(index show),
any_other_group: :index
}
```
Shortcuts are available for the `primary`, `secondary`, and `footer` groups. These enable us to write `action_link primary: :index` instead of `action_link groups: { primary: :index }`.
Link content is defined in a block. Each method called on the object passed into the block is converted into an attribute on the resulting HTML tag, except for these:
- `extra_class`: Adds one or more classes to the link. Takes either an `Array` or a `String`.
- `class`: **Replaces** the link's classes. Takes either an `Array` or a `String`.
- `type`: Allows the HTML tag to be changed. The only value currently implemented is `:button`. All others fall back on `<a>`.
#### Shortcuts
Four methods are available to define _common_ actions:
- `create_action_link`: adds a `create` link for a collection
- `show_action_link`: adds a `show` link on an instance
- `edit_action_link`: adds an `edit` link on an instance
- `destroy_action_link`: adds a `destroy` link on an instance
These are defined in the `AF83::Decorator::EnhancedDecorator` module.
### Behavior
The default behavior is as follows:
#### On the `index` page
Actions from the collection's `primary` group are rendered in the main section of the header (and retained in the "sticky" header). Below the main header, actions for the collection's `secondary` group are rendered.
In the `TableBuilderHelper`, all actions in the `primary`, `secondary`, and `footer` groups are rendered in a menu next to each instance, separated by group. The `footer` group always comes last.
#### On the `show` page
Actions from the object's `primary` group are rendered in the main section of the header (and retained in the "sticky" header). Below the main header, actions for the object's `secondary` group are rendered.
### Examples
#### Simple decorator
```ruby
class CalendarDecorator < AF83::Decorator
decorates Calendar
create_action_link
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link
instance_decorator.edit_action_link
instance_decorator.destroy_action_link do |l|
l.data {{ confirm: h.t('calendars.actions.destroy_confirm') }}
end
end
end
```
#### More complex decorator
```ruby
class LineDecorator < AF83::Decorator
decorates Chouette::Line
create_action_link do |l|
l.content t('lines.actions.new')
l.href { h.new_line_referential_line_path(context[:line_referential]) }
end
with_instance_decorator do |instance_decorator|
instance_decorator.show_action_link do |l|
l.content t('lines.actions.show')
l.href { [context[:line_referential], object] }
end
instance_decorator.action_link do |l|
l.content t('lines.actions.show_network')
l.href { [context[:line_referential], object.network] }
end
instance_decorator.action_link do |l|
l.content t('lines.actions.show_company')
l.href { [context[:line_referential], object.company] }
l.disabled { object.company.nil? }
end
can_edit_line = ->(){ h.policy(Chouette::Line).create? && context[:line_referential].organisations.include?(context[:current_organisation]) }
instance_decorator.with_condition can_edit_line do
edit_action_link do |l|
l.content {|l| l.primary? ? h.t('actions.edit') : h.t('lines.actions.edit') }
l.href { h.edit_line_referential_line_path(context[:line_referential], object.id) }
end
action_link on: :index, secondary: :index do |l|
l.content t('lines.actions.new')
l.href { h.new_line_referential_line_path(context[:line_referential]) }
end
end
instance_decorator.action_link policy: :deactivate, secondary: :show, footer: :index do |l|
l.content { h.deactivate_link_content('lines.actions.deactivate') }
l.href { h.deactivate_line_referential_line_path(context[:line_referential], object) }
l.method :put
l.data confirm: h.t('lines.actions.deactivate_confirm')
l.extra_class "delete-action"
end
instance_decorator.action_link policy: :activate, secondary: :show, footer: :index do |l|
l.content { h.activate_link_content('lines.actions.activate') }
l.href { h.activate_line_referential_line_path(context[:line_referential], object) }
l.method :put
l.data confirm: h.t('lines.actions.activate_confirm')
l.extra_class "delete-action"
end
instance_decorator.destroy_action_link do |l|
l.content { h.destroy_link_content('lines.actions.destroy') }
l.href { h.line_referential_line_path(context[:line_referential], object) }
l.data confirm: h.t('lines.actions.destroy_confirm')
l.extra_class "delete-action"
end
end
end
```
## Breadcrumb
The breadcrumb is built with the [Gretel](https://github.com/lassebunk/gretel) gem. Its configuration is stored in the `config/breadcrumbs.rb` file.
Clone repository

Coding Conventions