> ## Documentation Index
> Fetch the complete documentation index at: https://dub.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Ruby on Rails

> Learn how to integrate Dub with Ruby on Rails.

## 1. Prerequisites

To follow this guide, you will need to:

* [Create a Dub account](https://d.to/try)
* [Create an API key](https://app.dub.co/settings/tokens)

## 2. Install and initialize the Dub Ruby SDK

<Steps titleSize="h3">
  <Step title="Install">
    To install the [Dub Ruby SDK](https://dub.co/sdks/ruby), run the following command:

    ```bash bash theme={null}
    gem install dub
    ```
  </Step>

  <Step title="Initialize">
    Initialize the Dub Ruby SDK by creating a new instance of the `Dub` struct.

    ```ruby theme={null}
    class LinksController < ApplicationController
      require 'dub'

      before_action :initialize_dub

      def initialize_dub
        @dub = ::OpenApiSDK::Dub.new
        @dub.config_security(
          ::OpenApiSDK::Shared::Security.new(
            token: ENV['DUB_API_KEY']
          )
        )
      end
    end
    ```
  </Step>
</Steps>

## 3. Create link

Let's create a short link using the [Dub Ruby SDK](https://dub.co/sdks/ruby).

```ruby links_controller.rb theme={null}
def create
  req = ::OpenApiSDK::Operations::CreateLinkRequest.new(
    request_body: ::OpenApiSDK::Operations::CreateLinkRequestBody.new(
      url: 'https://google.com'
    )
  )

  res = @dub.links.create(req)

  render json: res.raw_response.body
end
```

<Accordion title="Full list of available attributes for the Link model">
  <ParamField body="url" type="string" required>
    The destination URL of the short link.
  </ParamField>

  <ParamField body="domain" type="string">
    The domain of the short link. If not provided, the primary domain for the
    workspace will be used (or `dub.sh` if the workspace has no domains).
  </ParamField>

  <ParamField body="key" type="string">
    The short link slug. If not provided, a random 7-character slug will be
    generated.
  </ParamField>

  <ParamField body="keyLength" type="number">
    The length of the short link slug. Defaults to 7 if not provided. When used
    with `prefix`, the total length of the key will be `prefix.length +
          keyLength`.
  </ParamField>

  <ParamField body="externalId" type="string | null">
    The ID of the link in your database. If set, it can be used to identify the
    link in future API requests (must be prefixed with 'ext\_' when passed as a
    query parameter). This key is unique across your workspace.
  </ParamField>

  <ParamField body="tenantId" type="string | null">
    The ID of the tenant that created the link inside your system. If set, it can
    be used to fetch all links for a tenant.
  </ParamField>

  <ParamField body="programId" type="string | null">
    The ID of the program the short link is associated with.
  </ParamField>

  <ParamField body="partnerId" type="string | null">
    The ID of the partner the short link is associated with.
  </ParamField>

  <ParamField body="folderId" type="string | null">
    The unique ID of an existing folder to assign the short link to.
  </ParamField>

  <ParamField body="prefix" type="string">
    The prefix of the short link slug for randomly-generated keys (e.g. if prefix
    is `/c/`, generated keys will be in the `/c/:key` format). Will be ignored if
    key is provided.
  </ParamField>

  <ParamField body="trackConversion" type="boolean" default={false}>
    Whether to track conversions for the short link. Defaults to `false` if not
    provided.
  </ParamField>

  <ParamField body="identifier" type="string | null">
    The identifier of the short link that is unique across your workspace. If set,
    it can be used to identify your short link for client-side click tracking.
  </ParamField>

  <ParamField body="archived" type="boolean" default={false}>
    Whether the short link is archived. Defaults to `false` if not provided.
  </ParamField>

  <ParamField body="publicStats" type="boolean" default={false}>
    Deprecated: Use `dashboard` instead. Whether the short link's stats are
    publicly accessible. Defaults to `false` if not provided.
  </ParamField>

  <ParamField body="tagIds" type="string | string[]">
    The unique IDs of the tags assigned to the short link.
  </ParamField>

  <ParamField body="tagNames" type="string | string[]">
    The unique name of the tags assigned to the short link (case insensitive).
  </ParamField>

  <ParamField body="comments" type="string | null">
    The comments for the short link.
  </ParamField>

  <ParamField body="expiresAt" type="string | null">
    The date and time when the short link will expire at.
  </ParamField>

  <ParamField body="expiredUrl" type="string | null">
    The URL to redirect to when the short link has expired.
  </ParamField>

  <ParamField body="password" type="string | null">
    The password required to access the destination URL of the short link.
  </ParamField>

  <ParamField body="proxy" type="boolean" default={false}>
    Whether the short link uses Custom Link Previews feature. Defaults to `false`
    if not provided.
  </ParamField>

  <ParamField body="title" type="string | null">
    The custom link preview title (og:title). Will be used for Custom Link
    Previews if `proxy` is true. Learn more: [https://d.to/og](https://d.to/og)
  </ParamField>

  <ParamField body="description" type="string | null">
    The custom link preview description (og:description). Will be used for Custom
    Link Previews if `proxy` is true. Learn more: [https://d.to/og](https://d.to/og)
  </ParamField>

  <ParamField body="image" type="string | null">
    The custom link preview image (og:image). Will be used for Custom Link
    Previews if `proxy` is true. Learn more: [https://d.to/og](https://d.to/og)
  </ParamField>

  <ParamField body="video" type="string | null">
    The custom link preview video (og:video). Will be used for Custom Link
    Previews if `proxy` is true. Learn more: [https://d.to/og](https://d.to/og)
  </ParamField>

  <ParamField body="rewrite" type="boolean" default={false}>
    Whether the short link uses link cloaking. Defaults to `false` if not
    provided.
  </ParamField>

  <ParamField body="ios" type="string | null">
    The iOS destination URL for the short link for iOS device targeting.
  </ParamField>

  <ParamField body="android" type="string | null">
    The Android destination URL for the short link for Android device targeting.
  </ParamField>

  <ParamField body="geo" type="object">
    Geographic targeting for the short link. Allows you to redirect users based on
    their location.
  </ParamField>

  <ParamField body="doIndex" type="boolean" default={false}>
    Allow search engines to index your short link. Defaults to `false` if not
    provided. Learn more: [https://d.to/noindex](https://d.to/noindex)
  </ParamField>

  <ParamField body="utm_source" type="string | null">
    The UTM source of the short link. If set, this will populate or override the
    UTM source in the destination URL.
  </ParamField>

  <ParamField body="utm_medium" type="string | null">
    The UTM medium of the short link. If set, this will populate or override the
    UTM medium in the destination URL.
  </ParamField>

  <ParamField body="utm_campaign" type="string | null">
    The UTM campaign of the short link. If set, this will populate or override the
    UTM campaign in the destination URL.
  </ParamField>

  <ParamField body="utm_term" type="string | null">
    The UTM term of the short link. If set, this will populate or override the UTM
    term in the destination URL.
  </ParamField>

  <ParamField body="utm_content" type="string | null">
    The UTM content of the short link. If set, this will populate or override the
    UTM content in the destination URL.
  </ParamField>

  <ParamField body="ref" type="string | null">
    The referral tag of the short link. If set, this will populate or override the
    `ref` query parameter in the destination URL.
  </ParamField>

  <ParamField body="webhookIds" type="string[] | null">
    An array of webhook IDs to trigger when the link is clicked. These webhooks
    will receive click event data.
  </ParamField>

  <ParamField body="testVariants" type="object[]">
    An array of A/B test URLs and the percentage of traffic to send to each URL.
    Requires 2-4 variants with percentages between 10-90.
  </ParamField>

  <ParamField body="testStartedAt" type="string | null">
    The date and time when the tests started.
  </ParamField>

  <ParamField body="testCompletedAt" type="string | null">
    The date and time when the tests were or will be completed.
  </ParamField>

  <ParamField body="tagId" type="string | null">
    Deprecated: Use `tagIds` instead. The unique ID of the tag assigned to the
    short link.
  </ParamField>
</Accordion>

Optionally, you can also pass an `externalId` field which is a unique identifier for the link in your own database to associate it with the link in Dub's system.

```ruby links_controller.rb theme={null}
def create
  req = ::OpenApiSDK::Operations::CreateLinkRequest.new(
    request_body: ::OpenApiSDK::Operations::CreateLinkRequestBody.new(
      url: 'https://google.com',
      external_id: '12345'
    )
  )

  res = @dub.links.create(req)

  render json: res.raw_response.body
end
```

This will let you easily [update the link](#5-update-link) or [retrieve analytics](#6-retrieve-analytics-for-link) for it later on using the `externalId` instead of the Dub `linkId`.

## 4. Upsert link

Dub Ruby SDK provides a method to upsert a link – where an existing link is updated if it exists, or a new link is created if it doesn't. so you don't have to worry about checking if the link already exists.

```ruby links_controller.rb theme={null}
def upsert
  req = ::OpenApiSDK::Operations::UpsertLinkRequest.new(
    request_body: ::OpenApiSDK::Operations::UpsertLinkRequestBody.new(
      url: "https://google.com",
    ),
  )

  res = @dub.links.upsert(req)

  render json: res.raw_response.body
end
```

This way, you won't have to worry about checking if the link already exists when you're creating it.

## 5. Update link

Let's update an existing link using the Dub Ruby SDK.

You can do that in two ways:

* Using the link's `linkId` in Dub's system.
* Using the link's `externalId` in your own database (prefixed with `ext_`).

```ruby links_controller.rb theme={null}
def update
  req = ::OpenApiSDK::Operations::UpdateLinkRequest.new(
    link_id: 'clx1gvi9o0005hf5momm6f7hj',
    request_body: ::OpenApiSDK::Operations::UpdateLinkRequestBody.new(
      url: 'https://google.uk'
    )
  )

  res = @dub.links.update(req)

  render json: res.raw_response.body
end
```

## 6. Retrieve analytics for link

Let's retrieve analytics for a link using the Dub Ruby SDK.

```ruby index.rb theme={null}
def analytics
  req = ::OpenApiSDK::Operations::RetrieveAnalyticsRequest.new(
    link_id: "clx1gvi9o0005hf5momm6f7hj",
    interval: ::OpenApiSDK::Operations::Interval::SEVEND,
    group_by: ::OpenApiSDK::Operations::GroupBy::TIMESERIES
  )

  res = @dub.analytics.retrieve(req)

  render json: res.raw_response.body
end
```

## 7. Examples

<CardGroup cols={2}>
  <Card title="Rails Example" icon="github" href="https://github.com/dubinc/examples/tree/main/ruby/rails/example" color="#333333">
    See the full example on GitHub.
  </Card>
</CardGroup>
