0

我需要找到一种解决方法,以便我可以按方法过滤我@events.is_near方法,然后按.sort_today范围对它们进行排序。

单独它们都可以工作,我可以.is_near毫无问题地定位到范围的末尾,但是我的结果被 中的默认排序参数所采用.is_near,我需要对它们进行排序.sort_today

有没有办法忽略.is_near返回/处理我的结果的方式?或者以某种方式将它们链接在一起@events.is_near(session[:city]).sort_today?目前我在像这样链接它们时收到此错误:#Array:0x007f8ca3c673c0 的未定义方法`sort_today'

这是我的模型:

class Venue < ActiveRecord::Base
  attr_accessible :name, :address, :latitude, :longitude

  has_many :events, :dependent => :destroy

  geocoded_by :address

  def self.is_near(city)
    self.near(city, 20, :units => :km).map(&:events).flatten
  end
end

class Event < ActiveRecord::Base
  attr_accessible :title, :details, :start_time, :end_time, :date, :cost, :venue_id

  belongs_to :venue

  scope :is_today, where(:date => Date.today)
  scope :sort_today, is_today.order(:start_time)

  class << self
    def is_near(*args, &block)
      Venue.is_near(*args, &block)
    end
  end
end

RubyGeocoder Venuegem 的地理编码也是如此,它包含所有事件。该.is_near方法必须在,Venue因为纬度和经度属性在那里。.is_near底部的方法Event本质上是一个重定向。(我试图让代表工作,但这是我能做到的唯一方法)

这是我的控制器:

class EventsController < ApplicationController
  def index
    @events = Event.sort_today.is_near(session[:city]) #returns results but sorted wrong
    #@events = Event.is_near(session[:city]).sort_today #returns undefined method `sort_today' error
  end
end

class ApplicationController < ActionController::Base
  before_filter :set_city
  def set_city
    unless session[:city].present?
      session[:city] = request.location.city
    end
  end
end

set_city方法只是获取用户通过输入字段输入的城市。

编辑:这是 Ruby Geocoder 文档的链接:https ://github.com/alexreisner/geocoder

4

2 回答 2

1

当你调用.map(&:events)Venue.is_near,它返回一个Array而不是一个AcitveRecord::Relation。这意味着当is_near被调用时,数据库查询会立即完成,而不是使用链式方法懒惰地评估查询。

我可以看到一些不同的方法来处理这个问题。

一种是在返回的 s 数组上调用Venue.is_near(session[:city])然后使用Array'方法在 Ruby 中进行排序。这可能会比在数据库中执行它要慢。sort_byEvent

另一种方法是将子句和子句join的评估移动到一个数据库查询中。我对地理编码器 gem 不是很熟悉,所以我不确定这是否适用。本质上,我希望能够在 join 上指定一个条件whereorder by

在事件中:

def self.nearby_sorted(location)
  Event.joins(:venue).where(venue: {near: location}).order("events.start_time")
end

但我不确定地理编码器gem是否会让你做这样的哈希条件:-/试一试并报告?

于 2013-09-18T01:38:47.913 回答
0

I got it to work by changing the scope location from in the Venue model to the Event model:

class Venue < ActiveRecord::Base
  attr_accessible :name, :address, :latitude, :longitude

  has_many :events, :dependent => :destroy

  geocoded_by :address
end

class Event < ActiveRecord::Base
  attr_accessible :title, :details, :start_time, :end_time, :date, :cost, :venue_id

  belongs_to :venue

  scope :is_today, where(:date => Date.today)
  scope :sort_today, is_today.order(:start_time)
  scope :is_near, lambda {|city| Venue.near(city, 20, :units => :km).map(&:events).flatten }
end

And this works in my controller: @events = @events.sort_today.is_near(session[:city])

TLDR: I removed the redirect methods and replaced it with a lambda

于 2013-09-18T04:03:47.577 回答