2012-07-09 70 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