2012-01-30 52 views
0

我一直在摸索着我的頭一陣子,雖然我確信它是一個愚蠢的錯誤,但我已經達到了必須諮詢的地步,如果我要保存我留下的毛囊。ActiveRecord查詢返回一個不正確的模型

我已經在Rails(3.1.2)中編寫了一個函數,它應該返回一個滿足特定標準的填充了ActiveRecord模型對象(在這種情況下爲用戶)的數組。標準是用戶的當前列表(由字段active_list_id表示)不能爲零。代碼如下:

def build_list_array 
    @lists = Array.new 
    User.all.each do |user| 
    @active_list_id = user.active_list_id 
    @lists<< List.find(@active_list_id) if @active_list_id != nil #TODO WHAT?!? WHY IS THIS RETURNING USERS? 
    end 
end 

正如你所看到的,我初始化一個空數組,通過所有用戶的循環和增加他們的活動列表的數組,如果用戶記錄相關的引用不是零。問題是,這是返回用戶對象,而不是列表對象。

下面是用戶和列表模式的關聯:

user model: 
    has_many :lists 
    has_many :tasks 

list model: 
    belongs_to :user 

關於參考的簡短到active_list:一個用戶可以有多個列表,但只有一個在任何時間處於活動狀態。因此,我需要在用戶記錄中引用該列表。那麼,活動列表就不是典型意義上的外鍵。

我感謝所有幫助您可以給我...謝謝=)

+1

我並沒有完全回答你的問題,而是IMO,最簡單的方法是:1.用'default:false'爲你的'lists'表添加一個布爾型字段2.添加'has_one:active_list,conditions:where( active:true)'到你的'User'模型。 3。將'scope:active,where(active:true)'添加到'List'模型中。 4.查詢'@lists = List.active'。在獎勵你有非常好的方法:'User.active_list','list.active?'等 – Damien 2012-01-30 21:37:14

+0

2.'has_one:active_list,class_name:'List',條件:['active =?',true]'這更好... – Damien 2012-01-30 21:47:07

回答

2

線取此,東西既然這樣,你的build_list_array將返回因爲each行爲的User陣列。當使用each迭代集合時,對each的調用返回原始集合。

例如,

list = [] 
# returns => [] 
[1,2,3,4,5].each { |number| list << number * 10 } 
# returns => [1, 2, 3, 4, 5] 
list 
# returns => [10, 20, 30, 40, 50] 

在你的代碼,你build_list_array方法的最後一條語句是each通話,意味着each返回值是什麼,是由該方法返回。如果您只是在方法的末尾添加return語句,那麼您將很好。

def build_list_array 
    @lists = Array.new 
    User.all.each do |user| 
    @active_list_id = user.active_list_id 
    @lists<< List.find(@active_list_id) if @active_list_id 
    end 
    return @lists # Actually return @lists 
end 

也就是說,你應該使用類似布拉德利的回答作爲更正確的Rails代碼的基礎。

+0

謝謝你對隱藏在明顯景象中的問題的非常詳細的解釋。非常感激。 – Chazu 2012-01-30 22:10:25

1

的ActiveRecord的阿雷爾是你的朋友在這裏:

User.where(:active_list_id.not_eq => nil) 
+0

我認爲not_eq方法是由metawhere gem或類似的提供的。 'User.where(User.arel_table [:active_list_id] .not_eq(nil))'是我可以在純粹的arel中完成的最好的。 – 2012-01-30 21:46:32

+0

這似乎是一個非常有吸引力的方式來做到這一點,我一直想要深入挖掘Arel。但是,爲了做這樣的事情,不需要實例化一個arel對象/表格嗎?謝謝你的幫助=) – Chazu 2012-01-30 22:14:25

+0

爲了公平起見,你不會在控制器 '範圍內:with_active_list,其中(arel_table [:active_list_id] .not_eq(nil))'稍微好一些,但不是那麼漂亮 – 2012-01-30 23:31:37

1

擴展史蒂芬的回答,得到列表

class User 
    belongs_to :active_list, :class_name => "List" 

def build_list_array 
    @lists = User.where('active_list_id is not null').map(&:active_list).compact 
+0

謝謝布拉德,這太好了。 – Chazu 2012-01-30 22:10:56

2

each總是返回它迭代的集合(不管塊內發生了什麼)。聽起來你想在方法結束時返回@lists

你似乎在很好奇地使用實例變量。你也可以在一個查詢通過加入沿

List.joins('inner join users on active_list_id =lists.id') 
+0

'好奇地使用實例變量'是一種方式,事實上,當我幾乎不知道自己在做什麼時,我寫了這些代碼(並不是說我現在很清楚自己有什麼想法),而且我從未使用過那些直到今天。感謝您的幫助=) – Chazu 2012-01-30 22:12:01

相關問題