如何在Ruby中简化活动记录查询

问题描述 投票:-1回答:2

我想根据国家,城市,州,角色和价目表进行过滤。如果用户选择任何单一手段或任何组合,它应该工作。这是我的搜索记录:

if params[:role].present?
  if params[:role] == 'role1'
    if params[:city_name].present?
      @matching_c = @matching_c.where(city_name: params[:city_name])
    elsif params[:state].present?
      @matching_c = @matching_c.where(state: params[:state])
    elsif params[:country].present?
      @matching_c = @matching_c.where(country: params[:country])
    end
    if params[:rate_card].present?
      @matching_c = @matching_c.joins(:rate_card).where("rate_cards.rate_card_type = ?", "#{params[:rate_card]}")
    end
    @matching_f = nil
  end
  if params[:role]  == 'role2'
    if params[:city_name].present?
      @matching_f = @matching_f.where(city_name: params[:city_name])
    elsif params[:state].present?
      @matching_f = @matching_f.where(state: params[:state])
    elsif params[:country].present?
      @matching_f = @matching_f.where(country: params[:country])
    end
    if params[:rate_card].present?
      @matching_f = @matching_f.joins(:rate_card).where("rate_cards.rate_card_type = ?", "#{params[:rate_card]}")
    end
    @matching_c = nil
  end
else
  if params[:city_name].present?
    @matching_f = @matching_f.where(city_name: params[:city_name])
    @matching_c = @matching_c.where(city_name: params[:city_name])
  elsif params[:state].present?
    @matching_f = @matching_f.where(state: params[:state])
    @matching_c = @matching_c.where(state: params[:state])
  elsif params[:country].present?
    @matching_c = @matching_c.where(country: params[:country])
    @matching_f = @matching_f.where(country: params[:country])
  end
  if params[:rate_card].present?
    @matching_c = @matching_c.joins(:rate_card).where("rate_cards.rate_card_type = ?", "#{params[:rate_card]}")
    @matching_f = @matching_f.joins(:rate_card).where("rate_cards.rate_card_type = ?", "#{params[:rate_card]}")
  end
end

这有效,但我想简化它。有人能帮忙吗?

ruby activerecord ruby-on-rails-5
2个回答
2
投票
def add_where(query, params)
  # FROM HERE
  field = %i(city_name state country).find { |x| params[x].present? }
  if field
    query = query.where(field => params[field])
  end
  # TO HERE

  if params[:rate_card].present?
    query = query.joins(:rate_card).where("rate_cards.rate_card_type = ?", params[:rate_card])
  end

  query
end

@matching_c = params[:role] != 'role2' ? add_where(@matching_c, params) : nil
@matching_f = params[:role] != 'role1' ? add_where(@matching_f, params) : nil

它只接受(城市,州,国家)中的一个,就像您的代码一样。如果您想接受任何组合,请使用此代替标记的代码:

%i(city_name state country).each { |field|
  query = query.where(field => params[field]) if params[field].present?
end

3
投票

您应该链接范围,而不是相互排除它们:

@matching_c = @matching_c.where(city_name: params[:city_name]) if
  params[:city_name].present?
@matching_c = @matching_c.where(state: params[:state]) if 
  params[:state].present?
@matching_c = @matching_c.where(country: params[:country]) if
  params[:country].present?
© www.soinside.com 2019 - 2024. All rights reserved.