# ...

class MyWorkflow < Temporalio::Workflow::Definition
  def execute
    # ...

    Temporalio::Workflow.upsert_search_attributes(MY_KEYWORD_KEY.value_set('some-new-value'))

    # ...
  end
end
```

---

## Rails integration - Ruby SDK

Temporal Ruby SDK is a generic Ruby library that can work in any Ruby environment.
However, there are some common conventions for Rails users to be aware of.

See the [rails_app sample](https://github.com/temporalio/samples-ruby/tree/main/rails_app) for an example of using Temporal from Rails.

## ActiveRecord

For ActiveRecord, or other general/ORM models that are used for a different purpose, it is not recommended to try to reuse them as Temporal models.
Eventually model purposes diverge and models for a Temporal workflows/activities should be specific to their use for clarity and compatibility reasons.
Also many Ruby ORMs do many lazy things and therefore provide unclear serialization semantics.
Instead, consider having models specific for Workflows/Activities and translate to/from existing models as needed.
See the [ActiveModel section](/develop/ruby/converters-and-encryption#active-model) on how to do this with ActiveModel objects.

## Lazy/Eager Loading

By default, Rails eagerly loads all application code on application start in production, but lazily loads it in non-production environments.
Temporal Workflows by default disallow use of IO during the Workflow run.
With lazy loading enabled in dev/test environments, when an Activity class is referenced in a Workflow before it has been explicitly required, it can give an error like:

```
Cannot access File path from inside a workflow. If this is known to be safe, the code can be run in a Temporalio::Workflow::Unsafe.illegal_call_tracing_disabled block.
```

This comes from bootsnap via zeitwerk because it is lazily loading a class/module at Workflow runtime.
It is not good to lazily load code during a Workflow run because it can be side effecting.
Workflows and the classes they reference should be eagerly loaded.

To resolve this, either always eagerly load (e.g. `config.eager_load = true`) or explicitly require what is used by a workflow at the top of the file.

Note, this only affects non-production environments.

---

## Schedules - Ruby SDK

This page shows how to do the following:

- [Schedule a Workflow](#schedule-a-workflow)
  - [Create a Scheduled Workflow](#create-a-workflow)
  - [Backfill a Scheduled Workflow](#backfill-a-scheduled-workflow)
  - [Delete a Scheduled Workflow](#delete-a-scheduled-workflow)
  - [Describe a Scheduled Workflow](#describe-a-scheduled-workflow)
  - [List a Scheduled Workflow](#list-a-scheduled-workflow)
  - [Pause a Scheduled Workflow](#pause-a-scheduled-workflow)
  - [Trigger a Scheduled Workflow](#trigger-a-scheduled-workflow)
  - [Update a Scheduled Workflow](#update-a-scheduled-workflow)
- [Use Start Delay](#start-delay)

## Schedule a Workflow {#schedule-a-workflow}

Scheduling Workflows is a crucial aspect of automation.
By scheduling a Workflow, you can automate repetitive tasks, reduce manual intervention, and ensure timely execution.

Use the following actions to manage Scheduled Workflows.

### Create a Scheduled Workflow {#create-a-workflow}

The create action enables you to create a new Schedule. When you create a new Schedule, a unique Schedule ID is generated, which you can use to reference the Schedule in other Schedule commands.

To create a Scheduled Workflow Execution in Ruby, use the [create_schedule](https://ruby.temporal.io/Temporalio/Client.html#create_schedule-instance_method)
method on the Client.
Then pass the Schedule ID and the Schedule object to the method to create a Scheduled Workflow Execution.
Set the Schedule's `action` member to an instance of `Temporalio::Client::Schedule::Action::StartWorkflow` to schedule a Workflow Execution.

```ruby
handle = my_client.create_schedule(
  'my_schedule_id',
  Temporalio::Client::Schedule.new(
    action: Temporalio::Client::Schedule::Action::StartWorkflow.new(
      MyWorkflow, 'some-input',
      id: 'my-workflow-id', task_queue: 'my-task-queue'
    ),
    spec: Temporalio::Client::Schedule::Spec.new(
      intervals: [
        Temporalio::Client::Schedule::Spec::Interval.new(
          every: 5 * 24 * 60 * 60.0, # 5 days
        )
      ]
    )
  )
)
```

:::tip Schedule Auto-Deletion

Once a Schedule has completed creating all its Workflow Executions, the Temporal Service deletes it since it won’t fire again.
The Temporal Service doesn't guarantee when this removal will happen.

:::

### Backfill a Scheduled Workflow {#backfill-a-scheduled-workflow}

The backfill action executes Actions ahead of their specified time range. This command is useful when you need to execute a missed or delayed Action, or when you want to test the Workflow before its scheduled time.

To backfill a Scheduled Workflow Execution in Ruby, use the [backfill](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#backfill-instance_method)
method on the Schedule Handle.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
now = Time.now(in: 'UTC')
handle.backfill(
  Temporalio::Client::Schedule::Backfill.new(
    start_at: now - (4 * 60),
    end_at: now - (2 * 60),
    overlap: Temporalio::Client::Schedule::OverlapPolicy::ALLOW_ALL
  )
)
```

### Delete a Scheduled Workflow {#delete-a-scheduled-workflow}

The delete action enables you to delete a Schedule. When you delete a Schedule, it does not affect any Workflows that were started by the Schedule.

To delete a Scheduled Workflow Execution in Ruby, use the [delete](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#delete-instance_method) method on the Schedule Handle.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
handle.delete
```

### Describe a Scheduled Workflow {#describe-a-scheduled-workflow}

The describe action shows the current Schedule configuration, including information about past, current, and future Workflow Runs. This command is helpful when you want to get a detailed view of the Schedule and its associated Workflow Runs.

To describe a Scheduled Workflow Execution in Ruby, use the [describe](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#describe-instance_method) method on the Schedule Handle.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
desc = handle.describe
puts "Schedule info: #{desc.info}"
```

### List a Scheduled Workflow {#list-a-scheduled-workflow}

The list action lists all the available Schedules. This command is useful when you want to view a list of all the Schedules and their respective Schedule IDs.

To list all schedules, use the [list_schedules](https://ruby.temporal.io/Temporalio/Client.html#list_schedules-instance_method) asynchronous method on the Client.
This returns an enumerator/enumerable.
If a schedule is added or deleted, it may not be available in the list immediately.

```ruby
my_client.list_schedules.each do |sched|
  puts "Schedule info: #{sched}"
end
```

### Pause a Scheduled Workflow {#pause-a-scheduled-workflow}

The pause action enables you to pause and unpause a Schedule. When you pause a Schedule, all the future Workflow Runs associated with the Schedule are temporarily stopped. This command is useful when you want to temporarily halt a Workflow due to maintenance or any other reason.

To pause a Scheduled Workflow Execution in Ruby, use the [pause](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#pause-instance_method) method on the Schedule Handle.
You can pass a note to the `pause` method to provide a reason for pausing the schedule.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
handle.pause(note: 'Pausing the schedule for now')
```

### Trigger a Scheduled Workflow {#trigger-a-scheduled-workflow}

The trigger action triggers an immediate action with a given Schedule. By default, this action is subject to the Overlap Policy of the Schedule. This command is helpful when you want to execute a Workflow outside of its scheduled time.

To trigger a Scheduled Workflow Execution in Ruby, use the [trigger](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#trigger-instance_method) method on the Schedule Handle.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
handle.trigger
```

### Update a Scheduled Workflow {#update-a-scheduled-workflow}

The update action enables you to update an existing Schedule. This command is useful when you need to modify the Schedule's configuration, such as changing the start time, end time, or interval.

To update a Scheduled Workflow Execution in Ruby, use the [update](https://ruby.temporal.io/Temporalio/Client/ScheduleHandle.html#update-instance_method) method on the Schedule Handle.
This method accepts a block which itself accepts an update input object and is expected to return an update with a new
schedule to update, or `nil` to not update.

```ruby
handle = my_client.schedule_handle('my-schedule-id')
handle.update do |input|
  # Return a new schedule with the action updated
  Temporalio::Client::Schedule::Update.new(
    schedule: input.description.schedule.with(
      # Update the action
      action: Temporalio::Client::Schedule::Action::StartWorkflow.new(
        MyNewWorkflow, 'some-new-input',
        id: 'my-workflow-id', task_queue: 'my-task-queue'
      )
    )
  )
end
```

## Use Start Delay {#start-delay}

Use the `start_delay` to schedule a Workflow Execution at a specific one-time future point rather than on a recurring schedule.

Use the `start_delay` parameter on either the `start_workflow` or `execute_workflow` methods in the Client.

```ruby
handle = my_client.start_workflow(
  MyWorkflow, 'some-input',
  id: 'my-workflow-id', task_queue: 'my-task-queue',
  start_delay: 3 * 60 * 60 # 3 hours
)
```

---

## Set up your local with the Ruby SDK