随机化DataMapper记录的顺序

时间:2012-07-09 22:58:32

标签: ruby sqlite sinatra datamapper

我只是希望以随机顺序返回DataMapper记录

这是我的模型(使用带有sqlite3数据库的DataMapper):

class Movie
  include DataMapper::Resource
  DataMapper::Property::String.length(255)

  property :id, Serial
  property :title, String
  property :img, String
  property :description, String
  property :year, String
  property :created_at, DateTime

  has n, :votes 
  belongs_to :user
end

以下是我如何归还记录(Sinatra)

get '/' do
  @movies = Movie.all # <-- What should this look like?
  haml :home
end

2 个答案:

答案 0 :(得分:2)

您也可以在SQL中执行此操作,例如:

class Movie
  # tons of other stuff here...

  def self.random
    repository(:default).adapter.select <<-SQL
      SELECT * FROM movies ORDER BY RANDOM()
    SQL
  end
end

然后你可以做

get '/' do
  @movies = Movie.random
  haml :home
end

如果您使用MySQL,则需要将RANDOM()替换为RAND()。请注意,Movie#random返回的对象不是Movie个对象且只读,但您可以像使用Movie个对象一样阅读属性,例如Movie.random.first.title获得第一部随机电影的标题。

最大的好处是,如果您的数据库中有很多记录并且只需要少量随机Movie,那么您不必获取所有电影并在之后对它们进行排序,但您可以使用SQL查询如下:

SELECT * FROM movies ORDER BY RANDOM() LIMIT 10

或者你可以将你的方法扩展到这样的东西:

class Movie
  # tons of other stuff here...

  def self.random(opts={})
    query = "SELECT * FROM movies ORDER BY RANDOM()"
    query << " LIMIT #{opts[:limit]}" unless opts[:limit].nil?
    repository(:default).adapter.select(query)
  end
end

允许编写如下查询:

Movie.random              # get all movies sorted randomly
Movie.random(:limit => 5) # get five random movies

答案 1 :(得分:1)

我相信你可以这样做(基于on this):

@movies = Movie.all.sort_by{rand}

此外,相同的帖子suggests Array#shuffle!会占用数组并将其随机播放,可能是这样的:

@movies = Movie.all.shuffle #no ! since you are not replacing the Array; not sure if DM supports it

- 或 -

@movies = Movie.all
@movies.shuffle!