Joe Morano
Joe Morano

Reputation: 1895

How to return records of associated models using Typeahead?

I'm using the twitter-typeahead-rails gem, which is built on typeahead and bloodhound. I'm using it to return results with AJAX while a user is typing into a search bar. Right now, it searches for instances of my model Product where product.name matches the search key. This part works great.

What I'm trying to do is return an associated record, along with the original result. My Product has a belongs_to relationship with Merchant. So for example, when I type in a search key, I want the results to also list the Merchant associated with each Product, like this:

return "<div>" + product.name + product.merchant.name +</div>";

but right now, adding product.merchant.name breaks the function, so I think the merchant isn't being included in the JSON. How do I include it?

Controller

def typeahead
  q = params[:query]
  render json: Product.where('name like ?', "%#{q}%")
end

HTML/JS

<%= form_tag products_path, :method => :get do %>
  <%= text_field_tag :search, params[:search], id:"typeahead" %>
    <%= image_tag("Go.png", type:"submit") %>
<% end %>


<script type="text/javascript">
  $(document).ready(function(){
    var bloodhound = new Bloodhound({
      datumTokenizer: function (d) {
        return Bloodhound.tokenizers.whitespace(d.value);
      },
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      remote: '/typeahead/%QUERY'
    });
    bloodhound.initialize();

    $('#typeahead').typeahead(null, {
      displayKey: function(product) {
        return "" + product.name + "";
      },
      source: bloodhound.ttAdapter(),
      templates: {
        suggestion: function (product) {
          var thing_url = "<%=root_url%>pages/"
          return "<div>" + product.name + </div>";
        }
      }
    });
  });
</script>

Gemfile

gem 'twitter-typeahead-rails', '0.10.5'

UPDATE:

I tried including Merchant in the query:

Product.includes(:merchants).where('name like ?', "%#{q}%")

and then tried returning the merchant.name in the results:

return "<div>" + product.name + product.merchant.name </div>";

but adding product.merchant.name breaks the function entirely, so now I'm getting no results at all.

Upvotes: 1

Views: 100

Answers (3)

hraynaud
hraynaud

Reputation: 756

When you render to JSON you have to explicitly tell ActiveModel Serializer to include the associated objects.

render :json => @products, :include => {:merchant=> {:only => :name}}

Upvotes: 1

Aleem
Aleem

Reputation: 680

try including merchants in query like this

Product.includes(:merchants).where('name like ?', "%#{q}%")

Upvotes: 1

Marcos R. Guevara
Marcos R. Guevara

Reputation: 6388

You can add the user id to product as something like owner_id, then you can query also with

@owner = User.find_by(id: @product.owner_id)

Upvotes: 0

Related Questions