In the Google Ads API, updates are done using a field mask. The field mask lists all
the fields you intend to change with the update, and any specified fields that
aren't in the field mask are ignored, even if sent to the server.

## FieldMaskUtil

The recommended way to generate field masks is using the built-in field mask
utility, which hides specific details and lets you generate field masks
automatically by monitoring the changes you make to the entity's fields.

The following example shows how to generate a field mask for updating a
campaign:

    campaign = client.resource.campaign
    campaign.resource_name = client.path.campaign(customer_id, campaign_id)

    mask = client.field_mask.with campaign do
      campaign.status = :PAUSED
      campaign.network_settings = client.resource.network_settings do |ns|
        ns.target_search_network = false
      end
    end

The code first creates an empty `Campaign` object, then sets its resource name
to inform the API of the campaign being updated.

This example uses the `client.field_mask.with` method on the campaign to begin
the block encompassing the updates. At the end of this block, the utility
compares the current state of the campaign after the block with the initial
state of the campaign before the block, and automatically produces a field mask
enumerating the changed fields. You can provide that field mask to the operation
when constructing it for the mutate call as follows:

    operation = client.operation.campaign
    operation.update = campaign
    operation.update_mask = mask

This method is recommended when you're building a complex operation and want
fine-grained control over every step. However, for most cases, you can pass the
resource name (or an existing resource instance) to the Ruby library factory
method:

    campaign_resource_name = client.path.campaign(customer_id, campaign_id)

    operation =
      client.operation.update_resource.campaign(campaign_resource_name) do |c|
        c.status = :PAUSED
        c.network_settings = client.resource.network_settings do |ns|
          ns.target_search_network = false
        end
      end

When given a resource name string, this method automatically creates a new
campaign resource with `resource_name` populated, constructs the field mask
based on changes you make within the block, builds the update operation, and
returns the final operation with `update` and `update_mask` already populated.
You can also pass an existing `Campaign` proto instance instead of a resource
name string to specify the starting state of the campaign. This pattern works
for all resources that support the update operation.

## Manually create a field mask

To create a field mask from scratch without using library utilities, create a
`Google::Protobuf::FieldMask`, make an array populated with the names of all the
fields you intend to change, and assign the array to the field mask's `paths`
field:

    mask = Google::Protobuf::FieldMask.new
    mask.paths = ['status', 'name']

## Update message fields and their subfields

`MESSAGE` fields can have subfields (such as
[`MaximizeConversions`](https://developers.google.com/google-ads/api/reference/rpc/v26/MaximizeConversions), which has three:
`target_cpa_micros`, `cpc_bid_ceiling_micros`, and `cpc_bid_floor_micros`), or
they can have none at all (such as [`ManualCpm`](https://developers.google.com/google-ads/api/reference/rpc/v26/ManualCpm)).

### Message fields with no defined subfields

When updating a `MESSAGE` field that is not defined with any subfields, use
`FieldMaskUtil` to generate a field mask, as presented earlier.

### Message fields with defined subfields

When updating a `MESSAGE` field that is defined with subfields without
explicitly setting any of the subfields on that message, you must manually add
each of the **mutable** `MESSAGE` subfields to the `FieldMask`, similar to the
earlier example that created a field mask from scratch.

One common example is updating a campaign's bidding strategy without setting any
of the fields on the new bidding strategy. The following example demonstrates
how to update a campaign to use the
[`MaximizeConversions`](https://developers.google.com/google-ads/api/reference/rpc/v26/MaximizeConversions) bidding strategy
without setting any of the subfields on the bidding strategy.

For this example, using the built-in comparison of `FieldMaskUtil` does not
achieve the intended goal.

The following code generates a field mask that includes `maximize_conversions`.
However, the Google Ads API doesn't allow this behavior in order to prevent
accidentally clearing fields and produces a
[`FieldMaskError.FIELD_HAS_SUBFIELDS`](https://developers.google.com/google-ads/api/reference/rpc/v26/FieldMaskErrorEnum.FieldMaskError#field_has_subfields) error.

> [!WARNING]
> **Warning:** The following code produces an error.

    # Creates a campaign with the proper resource name.
    campaign = client.resource.campaign do |c|
      c.resource_name = client.path.campaign(customer_id, campaign_id)
    end

    # Update the maximize conversions field within the update block, so it's
    # captured in the field mask.
    operation = client.operation.update_resource.campaign(campaign) do |c|
      c.maximize_conversions = client.resource.maximize_conversions
    end

    # Sends the operation in a mutate request that results in a
    # FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
    # be included in a field mask.
    response = client.service.campaign.mutate_campaigns(
      customer_id: customer_id,
      operations: [operation]
    )

> [!NOTE]
> **Note:** The following code properly updates a campaign to use the `MaximizeConversions` bidding strategy without setting any of its subfields.

    # Create the operation directly from the campaign's resource name. Don't do
    # anything in the block so that the field mask starts empty. You can modify
    # other fields in this block, except the message field intended to have a
    # blank subfield.
    campaign_resource_name = client.path.campaign(customer_id, campaign_id)
    operation = client.operation.update_resource.campaign(campaign_resource_name) {}

    # Manually add the maximize conversions subfield to the field mask so the API
    # knows to clear it.
    operation.update_mask.paths << 'maximize_conversions.target_cpa_micros'

    # This operation succeeds.
    response = client.service.campaign.mutate_campaigns(
      customer_id: customer_id,
      operations: [operation]
    )

## Clear fields

Some fields can be explicitly cleared. Similar to the previous example, you must
explicitly add these fields to the field mask. For example, assume you have a
campaign that uses a `MaximizeConversions` bidding strategy and that the
`target_cpa_micros` field is set with a value greater than `0`.

In `proto3`, setting a non-optional scalar field to its default value (`0`) is
indistinguishable from leaving it unset on a new message instance. As a result,
`FieldMaskUtil` adds `maximize_conversions` to the field mask instead of
`maximize_conversions.target_cpa_micros`, which causes a
[`FieldMaskError.FIELD_HAS_SUBFIELDS`](https://developers.google.com/google-ads/api/reference/rpc/v26/FieldMaskErrorEnum.FieldMaskError#field_has_subfields) error.

> [!WARNING]
> **Warning:** The following code produces an error.

    # Create a campaign object representing the campaign you want to change.
    campaign = client.resource.campaign do |c|
      c.resource_name = client.path.campaign(customer_id, campaign_id)
    end

    # The field mask in this operation includes 'maximize_conversions',
    # but not 'maximize_conversions.target_cpa_micros', so it results in an
    # error.
    operation = client.operation.update_resource.campaign(campaign) do |c|
      c.maximize_conversions = client.resource.maximize_conversions do |mc|
        mc.target_cpa_micros = 0
      end
    end

    # Operation fails because the field mask is invalid.
    response = client.service.campaign.mutate_campaigns(
      customer_id: customer_id,
      operations: [operation]
    )

> [!NOTE]
> **Note:** The following code properly clears the `target_cpa_micros` field on the `MaximizeConversions` bidding strategy.

    # Create a campaign including the maximize conversions fields right away, since
    # they are manually added to the field mask.
    campaign = client.resource.campaign do |c|
      c.resource_name = client.path.campaign(customer_id, campaign_id)
      c.maximize_conversions = client.resource.maximize_conversions do |mc|
        mc.target_cpa_micros = 0
      end
    end

    # Create the operation with an empty field mask. You can add a block here with
    # other changes that are automatically added to the field mask.
    operation = client.operation.update_resource.campaign(campaign) {}

    # Add the field to the field mask so the API knows to clear it.
    operation.update_mask.paths << 'maximize_conversions.target_cpa_micros'

    # Operation succeeds because the correct field mask is specified.
    response = client.service.campaign.mutate_campaigns(
      customer_id: customer_id,
      operations: [operation]
    )

Note that the automatic comparison approach works as intended for fields defined
as `optional` in the Google Ads API [protocol buffers](https://github.com/googleapis/googleapis/tree/HEAD/google/ads/googleads). Because
[`target_cpa_micros`](https://github.com/googleapis/googleapis/tree/HEAD/google/ads/googleads/v26/common/bidding.proto) is not an `optional` field on
`MaximizeConversions`, explicitly appending the path to `update_mask.paths` is
required to clear it.

> [!IMPORTANT]
> **Key Point:** If your intention is to clear a field, always explicitly add that field path to the field mask.