Ruby on rails Rails:在距离一个点10公里的范围内获得用户的帖子

Ruby on rails Rails:在距离一个点10公里的范围内获得用户的帖子,ruby-on-rails,ruby,model,geokit,Ruby On Rails,Ruby,Model,Geokit,我使用的是rails 3 geokit gem,它允许您在一个点的距离内找到用户,例如 User.within(10, origin: [51.123123, 0.1323123]) ['10'是以米/公里为单位的距离;51和0是纬度和经度] 我现在正试图获取距离某一点一定距离内的所有帖子。比如: Post.where(User.within(10, origin: [51.123123, 0.1323123])) Post.where(["user_id IN (?)", User.wit

我使用的是rails 3 geokit gem,它允许您在一个点的距离内找到用户,例如

User.within(10, origin: [51.123123, 0.1323123])
['10'是以米/公里为单位的距离;51和0是纬度和经度]

我现在正试图获取距离某一点一定距离内的所有帖子。比如:

Post.where(User.within(10, origin: [51.123123, 0.1323123]))
Post.where(["user_id IN (?)", User.within(10, origin: [51.123123, 0.1323123]).map { |u| u.id }])
(我的帖子模型属于我的用户模型,我的用户模型有很多帖子)

环顾四周,似乎解决方案在于.where,或者使用:through&:source,或者.joins,但我还没有确定下来


我将非常感谢任何帮助

可能有一个更优雅的解决方案,但我认为最简单的可能是与SQL一起使用。做一些类似于:

Post.where(User.within(10, origin: [51.123123, 0.1323123]))
Post.where(["user_id IN (?)", User.within(10, origin: [51.123123, 0.1323123]).map { |u| u.id }])

基本上,您只需发送一个
用户id的数组
Post.user\u id
可以匹配。

可能有一个更优雅的解决方案,但我认为最简单的可能是与SQL一起使用。做一些类似于:

Post.where(User.within(10, origin: [51.123123, 0.1323123]))
Post.where(["user_id IN (?)", User.within(10, origin: [51.123123, 0.1323123]).map { |u| u.id }])

基本上,您只需发送一组
用户id
帖子。用户id
可以匹配。

如果您的用户模型
有许多
帖子,为什么不直接加载它们呢

@posts = User.within(10, origin: [51.123123, 0.1323123]).collect(&:posts).flatten
map
的同义词,它有效地将一个数组转换为另一个数组,对原始数组的每个元素应用转换方法或块

在上面的命令中,
中的
是一个命名范围,它返回一个
用户数组
collect
将方法
posts
应用于每个用户,从而为每个用户生成一个posts数组。最后,
flatte
将posts数组(它是一个二维数组)压缩成一个大的posts数组

您还可以在
用户
模型中使用默认的
包含
,以防止在加载
帖子时出现错误


FWIW,我更喜欢使用ActiveRecord方法(关联等),而不是尽可能使用原始SQL。

如果您的用户模型
有许多
帖子,为什么不直接加载它们呢

@posts = User.within(10, origin: [51.123123, 0.1323123]).collect(&:posts).flatten
Post.joins(:user).merge(User.within(10, origin: [51.123123, 0.1323123]))
map
的同义词,它有效地将一个数组转换为另一个数组,对原始数组的每个元素应用转换方法或块

在上面的命令中,
中的
是一个命名范围,它返回一个
用户数组
collect
将方法
posts
应用于每个用户,从而为每个用户生成一个posts数组。最后,
flatte
将posts数组(它是一个二维数组)压缩成一个大的posts数组

您还可以在
用户
模型中使用默认的
包含
,以防止在加载
帖子时出现错误

FWIW,我更喜欢使用ActiveRecord方法(关联等),而不是尽可能使用原始SQL。

尝试以下解决方案:

Post.joins(:user).merge(User.within(10, origin: [51.123123, 0.1323123]))
class Post
  acts_as_mappable through: :user
end

Post.joins(:user).within(10, origin: [51.123123, 0.1323123])
尝试以下解决方案:

class Post
  acts_as_mappable through: :user
end

Post.joins(:user).within(10, origin: [51.123123, 0.1323123])


这管用!非常感谢。不过我同意,rails似乎有一个更为传统的解决方案,其中不需要
.map
部分。这就足够了:
Post.where(user\u id:user.within(10,origin:[51.123123,0.1323123])
。很抱歉,micha,这不起作用,我从“posts”中的“posts”中得到了“ActionView::Template::Error”(PGError:Error:subquery有太多的列,第1行:…CT COUNT(*)(选择…’这很有效!谢谢。不过我同意,rails似乎有一个更传统的解决方案,其中不需要
.map
部分。这就足够了:
Post.where(user\u id:user.within(10,origin:[51.123123,0.1323123])
。抱歉,micha,这不起作用,我得到了“ActionView::Template::Error”(PGError:ERROR:subquery的列太多,第1行:…CT COUNT(*)来自“posts”,其中“posts”。“user_id”位于(选择…'我不熟悉。收集,因此如果我做错了什么,请原谅我-将此行用作@posts,然后在视图中循环使用,这样做不起作用…我已在我的答案中添加了更多详细信息。希望这有帮助!对于之前的简短答案,我深表歉意:)这一点也不高效,对于每个用户来说,你都必须查询帖子……但这对我来说不起作用!我得到了“NoMethodError(未定义的方法“search”for#):”。事实上,我的行看起来像这样:user.within(1000,origin:@userlocation)。collect(&:posts)。flatte.search(params[:search])。order('created_at desc')。paginate(每页:7,第页:参数[:页])…但是搜索、排序和分页在jbarket上工作得很好。上面的映射解决方案…这里也应该没有吗?底线:TIMTOWTDI@YuriBarbashov我同意你的方法更有效。可以通过
includes
加载相关的帖子,以获得一些效率收益。@user1362141这是因为“搜索”方法没有为
Array
s:)不管怎样,我并不是想说我的答案是“最好的”。我不熟悉。收集,所以如果我做错了什么,请原谅我-将此行用作@posts,然后在视图中循环使用都不起作用…我已经为我的答案添加了更多细节。希望这有帮助!之前的简短回答让我感到抱歉:)这一点也不高效,对于每个用户来说,你都必须查询帖子……但这对我来说不起作用!我得到了“NoMethodError(未定义的方法“search”for#):”。事实上,我的行看起来像这样:user.within(1000,origin:@userlocation)。collect(&:posts)。flatte.search(params[:search])。order('created_at desc')。paginate(每页:7,第页:参数[:页])…但是搜索、排序和分页在jbarket上工作得很好。上面的映射解决方案…这里也应该没有吗?底线:TIMTOWTDI@YuriBarbashov我同意你的方法更有效。可以通过
includes
加载相关的帖子,以获得一些效率收益。@user1362141这是因为“搜索”方法没有为
Array
s:)不管怎样,我并不是想说我的答案是“最好的”。这看起来正是我所需要的!但我目前遇到了一个错误:“ActionView::Templat”