Search code examples
ruby-on-railssearchkick

How do I implement associations in searchkick


First, the example I read in the docs shows to declare the associated model as singular, :address, but if I do I get the error Association named 'address' was not found on User; If I change it to plural :addresses, then the next problem I have is the association doesn't work in views undefined method `country' for ... Why am I declaring the association as plural and how can I make the association available in the view

User.rb:

class User < ActiveRecord::Base
searchkick  word_middle: ['full_name', 'description', 'interests'] 
has_many :addresses
scope :search_import, -> { includes(:addresses) }

search.html.erb:


 <% @users.each do |u| %>
  <li> 
    <%= link_to "#{u.first_name} #{u.middle_name} #{u.last_name}", page_path(name: u.name) %>

        <% @ua=u.addresses.where("current=?", true) %>
        <% if @ua.country=="US" %>
            <%= @ua.city %>, <%= @ua.state %> <%= ISO3166::Country.find_country_by_alpha2(@ua.country) %>
        <% else %>
            <%= @ua.city %>, <%= ISO3166::Country.find_country_by_alpha2(@ua.country) %>
        <% end %>
  </li>
 <% end %>
</ul>


Solution

    • In controller, do this: @user = User.includes(:addresses).where(your_query) to make the association readily available in view.

    • And yes has_many associations are bound to be plural: "User has_one :life" and "User has_many :passions"; does it make sense?

    • And finally your error: where returns an array because you queried: "bring me all records which fulfill this condition". find, on the other hand, will bring back 1 specific record as it expects a unique attribute or brings back first record that matches that attribute.

    • What you need to do:

      You should either do this (if you are dead-sure that you will get 1 such record or you need only one of that type):

      <% @ua=u.addresses.where("current=?", true).first %>

      OR

      If you need to go through all the resultant array then:

      <% @ua=u.addresses.where("current=?", true) %>
      <% @ua.each do |ua| %>
        # Your code for each ua instead of @ua.
      <% end %>
    

    Happy Learning :)