【发布时间】:2019-09-09 21:12:11
【问题描述】:
我有一个房地产清单,其中每个房地产都有一些特点。然后,我有 2 张桌子:
- real_estates,用于存储用户添加的所有房地产。
- re_home_features,用于存储管理员添加的所有默认功能,如游泳池、壁橱、办公室、花园以及房地产可以拥有的许多功能
同一个房地产可以有很多特征,同样的特征可以有很多房地产。我创建了这些模型:
real_estate.rb
class RealEstate < ActiveRecord::Base
has_many :real_estate_home_features
has_many :re_home_features, as: :home_features, through: :real_estate_home_features, dependent: :destroy
end
re_home_features.rb
class ReHomeFeature < ActiveRecord::Base
has_many :real_estate_home_features
has_many :real_estates, through: :real_estate_home_features
end
real_estate_home_feature.rb
class RealEstateHomeFeature < ActiveRecord::Base
belongs_to :real_estate
belongs_to :re_home_feature
end
这样,多对多的关系就可以正常工作了。
我使用一些参数搜索房地产,例如:
- 客厅数量
- 浴室数量
- 售价(最低到最高)
- 总面积(最小到最大)
- 房地产代码
- 还有很多其他参数
我的搜索是这样的:
real_estates_controller.rb
def search
r = real_estates
r = r.where(code: params['code']) if params['code'].present?
r = r.where(city_name: params['city']) if params['city'].present?
r = r.where(garage: params['garage']) if params['garage'].present?
r = r.where(restrooms: params['restrooms']) if params['restrooms'].present?
r = r.paginate(:page => params[:page], :per_page => 10)
r
end
此搜索也运行良好。这样做没有问题,因为所有参数都在同一个表 real_estates 中。
但是现在,搜索有点复杂。我必须搜索具有特定功能的房地产。示例:我想要所有房地产,其中有 4 个卫生间、2 辆汽车在车库并且有 游泳池。
在我的示例中,搜索具有 4 个卫生间和 2 辆汽车的房地产给我返回了 50 个房地产,但其中只有 15 个房地产有游泳池。
如何过滤这 50 个不动产以仅显示与“池功能”相关的记录?
我无法在视图中进行验证,因为会导致每页的编号错误。我认为过滤器必须发生在数据库查询时刻,就在分页之前。
感谢您的帮助!
环境
rails -v: Rails 4.2.1
ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
so: Ubuntu 16.04.5 LTS
localhost database: MySQL (development)
server database: Postgres (production)
编辑 1
根据@jvillian 的回答,我将更改我的控制器,在查询中添加一个 JOIN。
if params['home_features'].present? && params['home_features'].any?
r = r.joins(:re_home_features).where(re_home_features: {id: params['home_features']}).distinct(:id)
end
在我的测试中,我有:
params['home_features'] = [1 , 2, 3]
我有 1 个具有这 3 个功能的房地产。但是,在视图中,我得到了相同的站点显示了 3 次。如果我添加了不同的,房地产只显示一次。但是...如果我将参数更改为:
params['home_features'] = [1 , 2, 3, 500]
我没有具有这 4 个功能的房地产,但结果是一样的。 没有明显区别,房地产被展示了3次。使用 dinstict,房地产显示一次。预期结果为零,因为我想要具有所有选定功能的房地产。
但我想我们快到了!我将提供一些关于我的模型的信息:
表格不动产
id | title | description | code | city_name | garage | ...
7 | Your House | Awesome... | 1234 | Rio de Janeiro | 4
表 re_home_features
id | name
1 | Pool
2 | Garden
3 | Tenis court
4 | Closet
table real_estate_home_features - 多对多关联
id | real_estate_id | re_home_feature_id
1 | 7 | 1
2 | 7 | 2
3 | 7 | 3
如果我跑:
r = r.joins(:re_home_features).where(re_home_features: {id: [1,2,3,500]}).distinct(:id)
我收到了这些查询(rails 控制台):
SELECT DISTINCT `real_estates`.* FROM `real_estates` INNER JOIN `real_estate_home_features` ON `real_estate_home_features`.`real_estate_id` = `real_estates`.`id` INNER JOIN `re_home_features` ON `re_home_features`.`id` = `real_estate_home_features`.`re_home_feature_id` WHERE `re_home_features`.`id` IN (1, 2, 3, 500)
它返回 1 个结果。房地产 id 7。如果我删除不同的,我有 3 个结果:相同的房地产,3 次。
预期结果为零。如果params['home_features'] = [1 , 2, 3] 我希望得到 1 个结果。
编辑 2
此连接方法有效,但返回类似于“OR”查询。就我而言,我需要一个带有“AND”的连接查询。查询必须是:“返回所有具有特征 1 AND 2 AND 3 的房地产”。
谢谢!
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 activerecord rails-activerecord ruby-on-rails-4.2