Rails: Filter based on multiple params?

心不动则不痛 提交于 2019-12-13 21:04:52

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/27756101/rails-filter-based-on-multiple-params

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!