CKP
CKP

Reputation: 87

Rails: Filter based on multiple params?

I have a simple app and the user can filter based on three different params by category, by discipline and by target group. All params are optional. So far it works, but the controller below is a bit bloated and I also think the three if statements are a bit messy.

Is there a cleaner way to do this?

def index
@listings = Listing.includes(:categorizations, :listing_disciplines, :listing_targets).page(params[:page])

if params[:category_id].present? && params[:category_id] != ""
  @category_id = Category.find_by(id: params[:category_id])
  @listings = @category_id.listings
end

if params[:discipline_id].present? && params[:discipline_id] != ""
  @discipline_id = Discipline.find_by(id: params[:discipline_id])
  @listings = @discipline_id.listings
end

if params[:target_id].present? && params[:target_id] != ""
  @target_id = Target.find_by(id: params[:target_id])
  @listings = @target_id.listings 
end

if params.blank?
  @listings   
end

And here's my listing model:

class Listing < ActiveRecord::Base
  has_many :categorizations, dependent: :destroy
  has_many :categories, through: :categorizations

  has_many :listing_disciplines, dependent: :destroy
  has_many :disciplines, through: :listing_disciplines

  has_many :listing_targets, dependent: :destroy
  has_many :targets, through: :listing_targets

  has_attached_file :image, styles: { :medium => "200x200#" }
  validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/

  validates :title, presence: true, uniqueness: true

  paginates_per 15

end

Upvotes: 0

Views: 2452

Answers (1)

ptd
ptd

Reputation: 3053

I'm not confident that your code even works, because you are resetting listings with each param. I assume you want to be able to filter by all three at once. A cleaner way would be:

def index
  @listings = Listing.joins(:categorizations, :listing_disciplines, :listing_targets)
  @listings = @listings.where("categorizations.category_id = ?", params[:category_id]) if params[:category_id].present? && params[:category_id] != ""
  @listings = @listings.where("listings_disciplines.discipline_id = ?", params[:discipline_id]) if params[:discipline_id].present? && params[:discipline_id] != ""
  @listings = @listings.where("listing_targets.target_id = ?", params[:target_id]) if params[:target_id].present? && params[:target_id] != ""
  @listings = @listings.page(params[:page])
end

This will make all filters cumulative.

Upvotes: 1

Related Questions