class Location < ActiveRecord::Base has_many :location_items has_many :items,:through=>:location_items end class Item < ActiveRecord::Base has_many :location_items has_many :locations,:through=>:location_items end class LocationItem < ActiveRecord::Base belongs_to :item belongs_to :location end
此外,我可以为项目模型启用全文搜索(来自gem),我可以这样做
Item.search(‘keyword’) – ‘search’是gem提供的范围,用于获取所有名称或描述匹配关键字的项目,结果项目添加了’rank’属性以匹配相关性
我也可以为位置模型启用Geo搜索(来自gem),我可以这样做
Location.near(‘Toronto.ON’,100)—‘near’是宝石提供的范围,用于获取距离多伦多100公里范围内的所有位置,结果位置添加了距离给定距离的“距离”属性location – 这个例子中的多伦多
所以现在我要做的是获取一个location_item对象列表,这些对象的位置匹配某个给定的位置和项目匹配给定的关键字.
例如,搜索匹配“关键字”且位于多伦多100公里范围内的location_item对象.
如何通过一个查询实现此目的?并且还可以通过location_item对象内的关联项和位置访问距离和排名属性.
我似乎无法链接范围,因为他们只处理Item和Location,而不是LocationItem,
例如,下面的表达式将不起作用
LocationItem.joins(:items,locations).search(‘keyword’).near(‘Toronto,ON’,100)
希望我对我想要做的事情的描述是有道理的.你有什么主意吗?非常感谢你!
解决方法
如果你想要一个查询,但不介意放弃你返回的元素的belongs_to接口:ActiveRecord :: Base自动分配查询的SELECT部分提供的属性,如下所示:Location.select( ‘id 1 as more_id’).first.more_id#=> 2这样您就可以使用它,并创建具有位置和item以及item_rank和location_dist的相应部分的属性.
class LocationItem < ActiveRecord::Base #This presumes that your geo and search gems actually return scopes that # properly respond to to_sql (which they should if you're using rails 3). def self.local_matching_items(text,dist=100) LocationItem .joins("INNER JOIN #{Item.search(text).to_sql} as matching_items on matching_items.id = location_items.item_id") .joins("INNER JOIN #{Location.near(dist).to_sql} as nearby_locations on nearby_locations.id = location_items.location_id") .select("location_items.id,nearby_locations.distance,matching_items.rank,nearby_locations.other_field_you_might_want as location_other_field_you_might_want,matching_items.name as item_name,etc") #returns LocationItems with #id,#distance,#rank,# location_other_field_you_might_want,#item_name,etc #It might be most helpful to distinguish between these # and normal location_item's by storing them in variables with a # different naming convention like nearby_item_matches. end end
*因为那时你会做两个查询,一个用于通过搜索提供商匹配关键字,一个用于从数据库中获取记录.
**如果您正在使用ThinkingSphinx,它已经支持searching by geographical distance,但您必须以不同方式定义索引并以不同方式调用LocationItem #search.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。