2012-07-09 48 views
1

我只是期待以随机顺序返回DataMapper记录DataMapper记录的随机订购

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

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 

这里是我如何返回记录(西纳特拉)

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

回答

1

我相信你可以做到这一点(基于on this):

@movies = Movie.all.sort_by{rand} 

而且,同样的岗位suggestsArray#shuffle!它会使用阵列和洗牌周围就那么可能是这样的:

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

- 或 -

@movies = Movie.all 
@movies.shuffle! 
+0

“@movies = Movie.all.shuffle!”与“@movies = Movie.all”有什么不同? @ movies.shuffle!'? – 2012-07-10 07:49:28

+0

@padde这是微妙的,但它是'@movies = Movie.all.shuffle' ...没有感叹号。 '!'表示你把原来的var中的内容覆盖掉了。由于'@movies = Movie.all.shuffle'段中'@ movies'没有任何内容可以覆盖,所以我离开了'!'。我只是不确定DM是否继承了这种方法,所以如果它不起作用,就提供了一种替代方法。 – ScottJShea 2012-07-10 15:34:20

+0

我的意思是在你的最后一个例子中,你实际上只是写了两行“Movie.all.shuffle!”。你仍然在'Movie.all'的返回值上调用mutator。所以说不应该叫'Movie.all.shuffle!'。但是因为'Movie.all'只是返回一个副本,所以无论如何,所以没关系。 – 2012-07-10 15:54:12

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的乳清,你需要用RAND()代替RANDOM()。请注意,由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 
+0

你能解释什么'库(:默认).adapter.select'正在做的sql语句之前?谢谢。 – pruett 2012-07-10 15:02:53

+0

'repository(:default)'只选择':default'版本库。您可以使用DataMapper中的多个数据存储(请参阅http://datamapper.org/docs/misc.html),但这对于大多数应用程序来说是无关紧要的。 'adapter'动态地获取相应的适配器(例如你的情况下的sqlite适配器),具体取决于你使用的数据库。最后,'select'在数据库上执行查询。 – 2012-07-10 15:30:27

+0

@pruett:我也编辑了我的答案,也许它是有帮助的。 – 2012-07-10 15:39:00