Im playing around Rails 7 + Turbo and I'm trying to create a form which has a dropdown of user lists. The form could create a new "Unit" record and assign users to this unit. The plan create a dropdown where you can search and select the owner of the unit record. The problem is turbo stream returns an extra data(the collection). I've checked the network request and apparently, the back-end is sending this template with extra data. How do i create a response without this extra data and just return the partial template?
the extra data
[#<User id: 4, email: "foo@bar.com", created_at: "2022-03-18 13:29:04.813660000 +0000", updated_at: "2022-03-18 13:29:19.397311000 +0000", first_name: nil, last_name: nil, phone: nil, meta: {}, account_id: 2>]
and this is the full response.
<turbo-stream action="update" target="owner_search_result"><template>
<li
id=user_4
class="hover:bg-blue-600 relative select-none py-2 pl-3 pr-9 text-gray-900 cursor-pointer" id="option-0"
role="option" tabindex="-1">
<span class="block truncate">
</span>
<span class="absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd" />
</svg>
</span>
<span class="ml-2 truncate text-gray-500">
foo@bar.com
</span>
</li>
[#<User id: 4, email: "foo@bar.com", created_at: "2022-03-18 13:29:04.813660000 +0000", updated_at: "2022-03-18 13:29:19.397311000 +0000", first_name: nil, last_name: nil, phone: nil, meta: {}, account_id: 2>]</template></turbo-stream>
this is the user controller
def search
keyword = user_params[:keyword] || ""
@users = User.filter_by_email(keyword)
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.update(:owner_search_result, partial: 'users/unit_owner', locals: { users: @users })
end
end
end
the partial is this
<%= @users.each do |user| %>
<li
id=<%= dom_id(user) %>
class="hover:bg-blue-600 relative select-none py-2 pl-3 pr-9 text-gray-900 cursor-pointer" id="option-0"
role="option" tabindex="-1">
<span class="block truncate">
<%= user.first_name %>
<%= user.last_name %>
</span>
<span class="absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd" />
</svg>
</span>
<span class="ml-2 truncate text-gray-500">
<%= user.email %>
</span>
</li>
<% end %>
Thank you so much.
Replace
<%= @users.each do |user| %>
at the beginning of your partial with
<% @users.each do |user| %>
because you do not want to render the return value of the each
call, which is the iterator itself, into the view. Note the =
that needs to be removed.