カスケード設定
GitLab 13.11で導入されました。
カスケード設定フレームワークにより、グループは基本的に祖先(グループ階層上の親グループ)やインスタンスレベルのアプリケーション設定から設定値を継承することができます。また、このフレームワークでは、設定値をより低い階層のグループに強制することもできます。
カスケード設定は現在、NamespaceSetting 内でのみ定義できますが、将来的には他のオブジェクトにも拡張される可能性があります。
新しいカスケード設定を追加
デフォルトでは、設定はカスケードされません。カスケード設定を定義するには、以下の手順を実行します:
- 
NamespaceSettingモデル内部で、cascading_attrヘルパー・メソッドを使用して新しい属性を定義します。一行で複数の属性を定義するために配列を使うことができます。class NamespaceSetting include CascadingNamespaceSettingAttribute cascading_attr :delayed_project_removal end
- 
データベースのカラムを作ります。 まったく新しい設定には、次のデータベースマイグレーションヘルパーを使うことができます。このヘルパーは4つのカラムを作成し、 namespace_settingsとapplication_settingsにそれぞれ2つずつ作成します。class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[2.1] include Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings enable_lock_retries! def up add_cascading_namespace_setting :delayed_project_removal, :boolean, default: false, null: false end def down remove_cascading_namespace_setting :delayed_project_removal end endカスケード設定に変換される既存の設定は、カラムを追加したり既存のカラムを変更したりするために個別のマイグレーションを必要とします。以下の仕様を使用して、必要に応じてマイグレーションを作成してください: - 
namespace_settingsテーブルのカラム:- 
delayed_project_removal:デフォルト値なし。ヌル値可。任意のカラム型を使用。
- 
lock_delayed_project_removal:ブール型カラム。デフォルト値はfalse。Null値は不可。
 
- 
- 
application_settingsテーブルのカラム:- 
delayed_project_removal:namespace_settingsで作成されたカラムのタイプ・マッチング。デフォルト値を任意に設定。Null 値は使用できません。
- 
lock_delayed_project_removal:ブール型カラム。デフォルト値はfalse。Null値は不可。
 
- 
 
- 
便利なメソッド
cascading_attr メソッドを使って属性を定義すると、いくつかの便利なメソッドが自動的に定義されます。
定義
cascading_attr :delayed_project_removal
利用可能な便利メソッド
- delayed_project_removal
- delayed_project_removal=
- delayed_project_removal_locked?
- delayed_project_removal_locked_by_ancestor?
- delayed_project_removal_locked_by_application_setting?
- 
delayed_project_removal?(ブール属性のみ)
- 
delayed_project_removal_locked_ancestor(ロックされたネームスペース設定オブジェクトを返します[namespace_id])
属性リーダーメソッド (delayed_project_removal)
属性リーダ・メソッド (delayed_project_removal) は、以下の基準で正しいカスケード値を返します:
- 属性が変更された場合、ダーティな値を返します。これにより、Railsの標準的なバリデータを属性に使用できるようになりますが、nilの値は許可する必要があります。
- ロックされた祖先の値を返します。
- ロックされたインスタンスレベルのアプリケーション設定値を返します。
- nil でない場合は、このネームスペースの属性を返します。
- 値が nil でない最も近い祖先の値を返します。
- インスタンスレベルのアプリケーション設定を返します。
_locked? メソッド
デフォルトでは、_locked? メソッド (delayed_project_removal_locked?) は、グループまたはアプリケーション設定の祖先が属性をロックしている場合、true を返します。属性をロックしたグループから呼び出された場合は、false を返します。
include_self: true が指定された場合、属性をロックしたグループから呼び出されるとtrue を返します。これは、例えば、属性がプロジェクトからロックされているかどうかをチェックする場合に関連します。
フロントエンドでのカスケード設定の表示
フロントエンドでカスケード設定を表示するために使えるRailsビューヘルパー、HAMLパーシャル、JavaScript関数がいくつかあります。
Railsビューヘルパー
cascading_namespace_setting_locked?
_locked? メソッド を呼び出して、設定がロックされているかどうかをチェックします。
| 引数 | 説明 | 種類 | 必須(デフォルト値) | 
|---|---|---|---|
| attribute | 設定の名前。例えば、 :delayed_project_removal。 | StringまたはSymbol | true | 
| group | 現在のグループ | Group | true | 
| **args | _locked?メソッドに渡す追加の引数。 | false | 
HAMLパーシャル
_enforcement_checkbox.html.haml
強制チェックボックスをレンダリングします。
| ローカル | 説明 | 種類 | 必須(デフォルト値) | 
|---|---|---|---|
| attribute | 設定の名前。例えば、 :delayed_project_removal。 | StringまたはSymbol | true | 
| group | 現在のグループ | Group | true | 
| form | Rails FormBuilder オブジェクト。 | ActionView::Helpers::FormBuilder | true | 
| setting_locked | 設定が祖先グループまたは管理者設定によってロックされている場合。 cascading_namespace_setting_locked?で計算できます。 | Boolean | true | 
| help_text | チェックボックスの下に表示されるテキスト | String | false(サブグループはこの設定を変更できません)。 | 
_setting_label_checkbox.html.haml
チェックボックス設定のラベルをレンダリングします。
| ローカル | 説明 | 種類 | 必須(デフォルト値) | 
|---|---|---|---|
| attribute | 設定の名前。例えば、 :delayed_project_removal。 | StringまたはSymbol | true | 
| group | 現在のグループ | Group | true | 
| form | Rails FormBuilder オブジェクト。 | ActionView::Helpers::FormBuilder | true | 
| setting_locked | 設定が祖先グループまたは管理者設定によってロックされている場合。 cascading_namespace_setting_locked?で計算できます。 | Boolean | true | 
| settings_path_helper | 先祖設定へのパスを生成するラムダ関数。例えば settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') } | Lambda | true | 
| help_text | チェックボックスの下に表示されるテキスト | String | false(nil) | 
_setting_label_fieldset.html.haml
fieldset 設定のラベルをレンダリングします。
| ローカル | 説明 | 種類 | 必須(デフォルト値) | 
|---|---|---|---|
| attribute | 設定の名前。例えば、 :delayed_project_removal。 | StringまたはSymbol | true | 
| group | 現在のグループ | Group | true | 
| setting_locked | 設定がロックされている場合。 cascading_namespace_setting_locked?で計算できます。 | Boolean | true | 
| settings_path_helper | 先祖設定へのパスを生成するラムダ関数。例えば -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') } | Lambda | true | 
| help_text | チェックボックスの下に表示されるテキスト | String | false(nil) | 
ロックアイコンにカーソルを置いたときにポップオーバーを表示するJavaScriptを初期化するために必要なmount要素をレンダリングします。このパーシャルはページごとに一度だけ必要です。
ジャバスクリプト
initCascadingSettingsLockPopovers
ロックアイコン({lock})にカーソルを合わせたときにポップオーバーを表示するために必要なJavaScriptを初期化します。この関数はインポートし、ページ固有のJavaScriptで呼び出す必要があります。
すべてをまとめる
-# app/views/groups/edit.html.haml
= render 'shared/namespaces/cascading_settings/lock_popovers'
- delayed_project_removal_locked = cascading_namespace_setting_locked?(:delayed_project_removal, @group)
- merge_method_locked = cascading_namespace_setting_locked?(:merge_method, @group)
= form_for @group do |f|
  .form-group{ data: { testid: 'delayed-project-removal-form-group' } }
    .gl-form-checkbox.custom-control.custom-checkbox
      = f.check_box :delayed_project_removal, checked: @group.namespace_settings.delayed_project_removal?, disabled: delayed_project_removal_locked, class: 'custom-control-input'
      = render 'shared/namespaces/cascading_settings/setting_label_checkbox', attribute: :delayed_project_removal,
          group: @group,
          form: f,
          setting_locked: delayed_project_removal_locked,
          settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') },
          help_text: s_('Settings|Projects will be permanently deleted after a 7-day delay. Inherited by subgroups.') do
        = s_('Settings|Enable delayed project deletion')
      = render 'shared/namespaces/cascading_settings/enforcement_checkbox',
          attribute: :delayed_project_removal,
          group: @group,
          form: f,
          setting_locked: delayed_project_removal_locked
  %fieldset.form-group
    = render 'shared/namespaces/cascading_settings/setting_label_fieldset', attribute: :merge_method,
        group: @group,
        setting_locked: merge_method_locked,
        settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') },
        help_text: s_('Settings|Determine what happens to the commit history when you merge a merge request.') do
      = s_('Settings|Merge method')
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :merge, s_('Settings|Merge commit'), help_text: s_('Settings|Every merge creates a merge commit.'), radio_options: { disabled: merge_method_locked }
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :rebase_merge, s_('Settings|Merge commit with semi-linear history'), help_text: s_('Settings|Every merge creates a merge commit.'), radio_options: { disabled: merge_method_locked }
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :ff, s_('Settings|Fast-forward merge'), help_text: s_('Settings|No merge commits are created.'), radio_options: { disabled: merge_method_locked }
    = render 'shared/namespaces/cascading_settings/enforcement_checkbox',
      attribute: :merge_method,
      group: @group,
      form: f,
      setting_locked: merge_method_locked
// app/assets/javascripts/pages/groups/edit/index.js
import { initCascadingSettingsLockPopovers } from '~/namespaces/cascading_settings';
initCascadingSettingsLockPopovers();
