2013-02-10 78 views
0

模型如何從Ruby表中返回一個唯一的隨機行?

class Answer < ActiveRecord::Base 
def self.energy(v, w) 
    a = self.where('energy_id = ? AND weight = ?', v, w) 
    a.offset(rand(a.count)).first.name 
end 

視圖

<%= form_for(@answer) do |f| %> 
    <%= f.submit "#{Answer.energy(3, 1)}", name: "answer", class: "btn" %> 
    <%= f.submit "#{Answer.energy(4, 1)}", name: "answer", class: "btn" %> 
<% end %> 

我有,它返回一個隨機值,正常。我打電話給這36次(18對2),而且我不希望相同的價值不止一次地返回。我嘗試了各種.pop變化,但每次都失敗。

感謝您的幫助!

爲號召,我使用這些表單按鈕,所以我去了:

<% names = [] %> 

<div id='one' class='center'> 
    <%= form_for(@answer) do |f| %> 
    <%= f.submit "#{record = Answer.energy(3, 1, names)}", name: "answer", class: "btn btn-large btn-primary" %> 
    <% names << record %> 
    <%= f.submit "#{record = Answer.energy(4, 1, names)}", name: "answer", class: "btn btn-large btn-primary" %> 
    <% names << record %> 
    <% end %> 
</div> 
~~ 17 more times ~~ 

的作品就像一個魅力!謝謝,jvnill,尋求幫助!

+0

你調用方法'energy' 16次,或者你只是想16個唯一行? – texasbruce 2013-02-10 02:06:38

+0

您使用的是什麼ORM? ActiveRecord的? – 2013-02-10 03:19:31

+0

是的。 ActiveRecord :: Base – Dudo 2013-02-10 07:36:06

回答

2

你可以使用.order("RAND()")爲mysql,.order("RANDOM()")爲postgre。

UPDATE:no duplicates。

def self.energy(v, w) 
    where('energy_id = ? AND weight = ?', v, w).limit(16).uniq.pluck(:name) 
end 

更新:16次,沒有重複的

它返回匹配的能量和重量,不包括在except_names

# model 
def self.energy(v, w, except_names = []) 
    klass = where('energy_id = ? AND weight = ?', v, w) 
    klass = klass.where('name NOT IN (?)', except_names) if except_names.any? 
    klass.order('RAND()').first.name 
end 

這種調用方法16倍,第隨機記錄,每次向名稱中添加uniq名稱

# how to call 
names = [] 
16.times do 
    if record = Model.energe(1, 1, names) 
    names << record 
    end 
end 
+0

我知道如何以隨機順序獲取它們。 'rand()'命令可以獲得一個隨機集合。我所追求的是一旦給出一行就不會重複。基本上,我希望它像'.pop'方法一樣工作。返回值,然後將其從哈希中刪除。 – Dudo 2013-02-10 01:55:18

+0

對不起,我的答案更新爲不返回重複的名稱。 – jvnill 2013-02-10 02:08:45

+0

nope。聽起來不錯,但沒有骰子。你在那裏得到的結果是整個哈希值。 '.pluck(:name)'表示只顯示哈希的名稱列,這是一個很好的方法。但我得到9次結果爲每個電話(而不是一個) – Dudo 2013-02-10 07:35:37

1
def self.energy(v, w) 
    c = [] 
    a = self.where('energy_id = ? AND weight = ?', v, w) 
    b = a.offset(rand(a.count)).first.name 
    unless c.include?(b) do 
    puts b 
    c << b 
    end 
end 
+0

這會導致一堆空的結果。但它確實看起來像你在做什麼。返回b,然後將b包含到c中...然後下一次調用它時,c將會包含一些東西,並且不會包含在返回中。 – Dudo 2013-02-10 07:46:18

1

如果你調用它16次,你可以傳遞已經存在的行作爲參數嗎?如果是,那麼這項工作?

def self.energy(v, w, records = []) 
    a = self.where("energy_id = ? AND weight = ? AND id NOT IN ('-1',?)", v, w, Array(records).map(&:to_param)) 
    a.offset(rand(a.count)).first.name 
end 

用法:

records = [] 
16.times do 
records << Answer.energy(10, 5, records) 
end 

你也可以傳遞一個數組,而不是單個記錄:

other_record = Answer.energy(10,5) 
Answer.energy(10, 5, other_record) 
+0

對不起,你失去了我=/ – Dudo 2013-02-10 07:50:01

+0

你需要跟蹤你已經提取的記錄並將它們傳遞到你的SQL查詢中,以便它不會獲取它。您可以構建助手或演示者類,以便更輕鬆地進行跟蹤。 – 2013-02-10 18:00:31

+0

我明白你的意思了! – Dudo 2013-02-10 20:41:19

相關問題