Ruby on Rails:搜索has_many与内连接和其他条件的关联

时间:2011-02-08 14:25:09

标签: ruby-on-rails search join has-many

我一直在寻找这个问题,我无法在任何地方找到答案。 我有一个基本的搜索功能,找到房子,一切正常,直到目前为止,获得房屋的主要部分看起来像这样(条件是例如):

@houses = House.all(
    :conditions => ["houses.province_id = ? AND open_houses.date > ? AND houses.surface = ?", "4", "Tue, 08 Feb 2011", "125"],
    :select => 'distinct houses.*',
    :joins => "INNER JOIN open_houses ON open_houses.house_id = houses.id" )

现在,我有一个关于房子规格(如阳台,游泳池等)的has_many协会。 为此,我有标准的设置。 spec-names的表,以及带有house_id和specification_id的表。

但现在,我需要将这些添加到搜索功能中。所以有人可以找到一个带游泳池和阳台的房子。

我确信有一个解决方案,但我只是不知道将它放在代码中的位置,以及如何...谷歌只是让我喜欢它的页面,而不是解释这个的页面。

这就是我的params的样子:

Parameters: {"dateto"=>"", "commit"=>"ZOEKEN!", "pricefrom"=>"", "location"=>"", "province_id"=>"4", "rooms"=>"", "datefrom"=>"", "surface"=>"125", "utf8"=>"✓", "priceto"=>"", "filters"=>{"by_specifications"=>["2", "5", "10"]}, "house_category_id"=>""}

希望有人可以提供帮助,如果有什么不清楚的地方请告诉我。

由于

修改 哦,我已经有了它的工作!非常感谢!

只有一个小问题:如果房子中存在任何一个规格,房子就会出现..所以这是一个OR-OR查询,但我想要的是AND-AND ..

因此,如果用户搜索阳台和车库,那么房子必须出现,如果这两个房子都存在。 我现在做的是:对于搜索的每个规范,正在进行查询..(代码在下面)

我想知道,这是正确的方法吗? 因为它有效,但我得到了双重匹配..(我使用“uniq”过滤它们) uniq的问题在于我无法使用“will_paginate”来处理它..

这是我的最终代码:

def index
  ActiveRecord::Base.include_root_in_json = false

  # I'm creating conditions with a function I made, PM me for the code..
  conditions = createConditions( createParameters( ) );

  query = House.includes( :open_houses ).where( conditions )

  unless params[:specifications].blank?
    query = query.joins( :house_specifications )
    query = query.group( 'open_houses.id' )
    query = query.where( 'house_specifications.specification_id' => params[:specifications] )
    query = query.order( 'count(open_houses.id) DESC' )
    # query = query.having( 'count(open_houses.id) = ?', [params[:specifications].length.to_s] )
  end

  query = query.order( (params[:sort].blank?)? "open_houses.date ASC, open_houses.from ASC" : params[:sort] )

  if params[:view] == "list"
    page = params[:page] unless params[:page].blank?
    @houses = query.all.uniq.paginate( :page => page || "1", :per_page => 5 )
  else
    @houses = query.all.uniq
  end

  respond_to do |format|
    format.html
    format.js
  end
end

感谢您的帮助,非常感谢!

1 个答案:

答案 0 :(得分:1)

试试这个(Rails 3):

House.joins(:houses_specifications).
      where('houses_specifications.specification_id' => params[:by_specifications]).
      where(...).all

在查询中运行最终.all之前,您可以添加一些if和case来添加过滤器,group_by,限制等。

house_query = House.where(:pink => true)
unless params[:by_specifications].blank?
  house_query = house_query.joins(:houses_specifications).
                            where('houses_specifications.specification_id' => params[:by_specifications])
end
...
@houses = house_query.all

修改 新的和改进的版本,不直接在连接表上查询以便于阅读,group_by用于清晰度,并且相交以获得具有所有规格的房屋。

query = House.joins(:open_houses).where(conditions)

unless params[:specifications].blank?
  query = query.joins(:specifications).
                group('houses.id').
                where(:specifications => params[:specifications]).
                having('count(*)=?', params[:specifications].count)
end

if params[:view] == "list"
  @houses = query.all.paginate(:page => params[:page])
else
  @houses = query.all
end

您可以将“拥有”更改为“订单”,以便首先获得具有最匹配规格的那些。