TangoKilo
TangoKilo

Reputation: 1785

Rails has many through search function using an associated model

Basically in my application a song has many categories and a category has many songs, through a joining model called categorizations.

I basically have a search function in the song model which looks like this at the moment:

def self.search(search)
    if search
      find(:all, conditions: ['title LIKE ?', "%#{search}%"], order: 'title')
      find(:all, conditions: ['lyrics LIKE ?', "%#{search}%"], order: 'title')
    else
      #if nothing is inputed then just show all songs
      find(:all, order: 'title')
    end
  end

And that works fine as title and lyrics are part of the song model. However I'm not sure how I'd go about adding a function so that you can input the category description (the only attribute that the category model has) and have it return that in the search results as well, given that it's in a separate model. Thanks in advance for any help!

Upvotes: 0

Views: 171

Answers (1)

rogal111
rogal111

Reputation: 5933

Use ActiveRecord includes method.

 class Song < ActiveRecord::Base
   has_many :categorizations
   has_many :categories, :through=>:categorizations

   def self.search(search)
    res=includes(:categories).order('title')
    res=res.where('title LIKE :search OR lyrics LIKE :search',:search=>"%#{search}%") if search
    res
  end

  def self.search_by_category_desc(search)
    res=joins(:categories).order('title')
    res=res.where('categories.description LIKE ?',"%#{search}%") if search
    res
  end

  def self.search_by_title_or_lirics_or_cat_desc(search)
    res=includes(:categories).order('title')
    res=res.where('title LIKE :search OR categories.description LIKE :search OR lyrics LIKE :search',:search=>"%#{search}%") if search
    res
  end
 end

This will preload all categories for searched songs.

Remember about difference between joins and includes: What's the difference between "includes" and "joins" in ActiveRecord query?

Upvotes: 1

Related Questions