1

我被这个难住了:

我正在尝试对控制器中的数组进行排序,如下所示:

控制器

@sorted = sort_by_reviews(@search, "count")

模型

def self.sort_by_reviews(array, type)
if type == "count"
  array.sort! { |x, y| y.reviews.count <=> x.reviews.count }
else
  array.sort! { |x, y| y.reviews.average.to_f <=> x.reviews.average.to_f }
end

结尾

但是,我收到此错误:

undefined method `sort_by_reviews' for #<BuildingsController:0x007f80d89be320>

令人困惑的是,当我在控制器中执行此操作时:

@sorted = @search.sort! { |x, y| y.reviews.count <=> x.reviews.count }

它工作正常。

我究竟做错了什么?

- -更新

我的完整控制器代码:

@search = Model.search_attributes(params[:search])
@sorted = @search.sort_by_reviews "count"

我的调整模型方法:

def sort_by_reviews(type)
if type == "count"
   self.sort! { |x, y| y.reviews.count <=> x.reviews.count }
 else
   self.sort! { |x, y| y.reviews.average.to_f <=> x.reviews.average.to_f }
 end
end

我仍然得到同样的错误:

undefined method `sort_by_reviews' for #<Array:0x007f80d423ee50>
4

3 回答 3

3

sort_by_reviews在模型上定义为类方法,但在控制器上将其作为实例方法调用。我必须查看更多代码才能获得有关如何进行的建议,但可能会将模型更改为:

def sort_by_reviews(type)
  if type == "count"
    self.sort! { |x, y| y.reviews.count <=> x.reviews.count }
  else
    self.sort! { |x, y| y.reviews.average.to_f <=> x.reviews.average.to_f }
  end
end

和控制器

@sorted = @search.sort_by_reviews "count"
于 2013-06-11T03:49:26.573 回答
2

控制器:

@sorted = sort_by_reviews(@search, "count")

模型:

def self.sort_by_reviews(array, type)
if type == "count"
  array.sort! { |x, y| y.reviews.count <=> x.reviews.count }
else
  array.sort! { |x, y| y.reviews.average.to_f <=> x.reviews.average.to_f }
end

在模型中,您使用的是类方法。因此,在控制器中,您只需这样称呼它:

@sorted = ModelName.sort_by_reviews(@search, "count")

例如,您的型号名称是Foo,这意味着:

@sorted = Foo.sort_by_reviews(@search, "count")
于 2013-06-11T04:08:12.357 回答
0

虽然 Rajendran 的回答有效,但我真的不喜欢这种结构。您正在 Model 类上实现一个方法,该方法根据参数对数组进行就地排序。有趣且可重用的代码片段是获取 Model 类的对象并比较它们的部分。应该提取该代码,以便可以在需要比较模型对象的任何地方使用它。

像这样的东西:

class Model
  def self.compare_by_reviews_count_desc(x,y)  # Descending order of review count
    y.reviews.count <=> x.reviews.count
  end

  def self.compare_by_reviews_average_desc(x,y) # Descending order of review average
    y.reviews.average.to_f <=> x.reviews.average.to_f
  end

  # These functions return method objects for use in other functions
  def self.reviews_count_desc_sorter  
    method(:compare_by_reviews_count_desc)
  end

  def self.reviews_average_desc_sorter
    method(:compare_by_reviews_average_desc)
  end
end

然后在你的控制器中,因为@search是一个模型数组,而不是

@sorted = sort_by_reviews(@search, "count")

你将会拥有

@sorted = @search.sort &Model.reviews_count_desc_sorter

然后,如果您想按平均评论排序,您将拥有

@sorted = @search.sort &Model.reviews_average_desc_sorter

它有点冗长,但现在你有能力sort或者sort!你正在排序的集合类型的细节没有嵌入到模型中,而如何进行比较的细节仍然封装在模型中。

于 2013-06-11T07:44:26.217 回答