Using hotwire-combobox with prefixed_ids

Published on 2024-11-29

Last updated on 2025-01-13

I’ll skip the install part and directly go to the solution.

Preface

I have an Account model that I want to use with hotwire combobox, and I have set prefixed_id by using prefixed_ids. here is the code.

class Account < ApplicationRecord
  has_prefix_id :acct

  # Later to be used in async search options
  scope :search, ->(q) { q.blank? ? all : where("name like ?", "%#{q}%") }

  # we need to define this function, so that hotwire combobox can render.
  def to_combobox_display
    name
  end
end

Setup hotwire combobox

first, add it to the form.

<%= f.combobox :account_id, accounts_path %>

then, in our controoler, setup query.

class AccountsController < ApplicationController
  def index
    @accounts = Account.search(params[:q])
  end
end

in erb file(hint: we are using turbo_stream.erb, not the regular html.erb).

<%# app/views/accounts/index.turbo_stream.erb %>
<%= async_combobox_options @accounts, 
    render_in: { partial: "accounts/account", next_page: nil } %>
<%# app/views/accounts/_account.turbo_stream.erb %>
<div>
  <%= account.name %>
</div>

now, we have a working hotwire combobox. but there’s one problem. the returning value is the actual database id, but we want the value return acct_xxxxx like value.

The answer

it turns out that in hotwire combobox, we can pass value to the async_combobox_options. now, let’s do it.

<%= async_combobox_options @accounts,
    render_in: { partial: "accounts/account", next_page: nil, },
    value: :to_param
%>

with this one simple change, we now returning the prefixed value to the frontend!