2010-01-28 59 views
7

說我有具有附接的狀態下的關聯:有什麼用途:belongs_to關聯的條件是什麼?

belongs_to :admin_user, 
    :class_name => 'User', 
    :foreign_key => :admin_user_id, 
    :conditions=> 'users.admin=TRUE' # or any variation with hash or array, {:admin => true}, etc. 

API doc states使得:上belongs_to的條件選項:

指定該 相關聯的對象必須按順序 符合條件被包括爲WHERE SQL 片段,例如授權= 1。

但是輸出在select上沒有顯示WHERE子句,並且在任何情況下我都希望在belongs_to上這樣的條件會阻止以INSERT而不是SELECT開頭的關係開始。這個選項似乎對belongs_to關聯沒有影響,除非我遺漏了一些東西。該選項在has_many上有意義,我只是看不出它適用於belongs_to。

編輯:進一步的研究顯示,你確實可以堅持一個違反條件的關聯,但你不能在之後檢索關聯記錄記錄被重新加載。

像這樣定義一個類:

class Widget < ActiveRecord::Base 

    belongs_to :big_bloop, 
     :class_name => "Bloop", 
     :foreign_key => :big_bloop_id, 
     :conditions => ["big_bloop = ?", true] 

    belongs_to :bloop, :conditions => ["big_bloop = ?", true] 

end 

...從我們看到控制檯:

>> bloop = Bloop.new 
=> #<Bloop id: nil, name: nil, big_bloop: nil> 
>> widget = Widget.new 
=> #<Widget id: nil, name: nil, bloop_id: nil, big_bloop_id: nil> 
>> widget.bloop = bloop 
=> #<Bloop id: nil, name: nil, big_bloop: nil> 
>> widget.save! 
=> true 
>> widget 
=> #<Widget id: 2, name: nil, bloop_id: 2, big_bloop_id: nil> 

我有關違反條件並保存它BLOOP。該關聯被持久化到數據庫(參見上面最後一行的bloop_id和big_bloop_id)。

>> big_bloop = Bloop.new 
=> #<Bloop id: nil, name: nil, big_bloop: nil> 
>> widget.big_bloop = big_bloop 
=> #<Bloop id: nil, name: nil, big_bloop: nil> 
>> widget.save! 
=> true 
>> widget 
=> #<Widget id: 2, name: nil, bloop_id: 2, big_bloop_id: 3> 

相同的東西,不同的屬性。

>> widget.bloop 
=> #<Bloop id: 2, name: nil, big_bloop: nil> 
>> widget.big_bloop 
=> #<Bloop id: 3, name: nil, big_bloop: nil> 

這兩個無效的bloops都保留在內存中。

>> widget.reload 
=> #<Widget id: 2, name: nil, bloop_id: 2, big_bloop_id: 3> 
>> widget.bloop 
=> nil 
>> widget.big_bloop 
=> nil 

重新加載後,它們消失了,因爲SELECT語句確實使用WHERE子句排除它們。

Bloop Load (0.3ms) SELECT * FROM `bloops` WHERE (`bloops`.`id` = 2 AND (big_bloop = 1)) 

然而小部件仍具有參考:

>> widget 
=> #<Widget id: 2, name: nil, bloop_id: 2, big_bloop_id: 3> 

似乎很奇怪我,但你去那裏。

回答

4

這是一個很好的發現!

我首先想到的是,這可能只是AssociationProxy基類或類似的一些通用的東西。但挖進一步下跌,似乎有特定的選項列表belongs_to的許可證:

@@valid_keys_for_belongs_to_association = [ 
    :class_name, :primary_key, :foreign_key, :foreign_type, :remote, :select, :conditions, 
    :include, :dependent, :counter_cache, :extend, :polymorphic, :readonly, 
    :validate, :touch 
] 

因此,在某些時候,可能潛意識作出決定,把存在。 :)

我不知道你怎麼測試的WHERE,雖然。我的測試清楚地表明它確實包括在WHERE子句:

class Thing < ActiveRecord::Base; end 

class Widget < ActiveRecord::Base 
    belongs_to :thing, :conditions => ['name = ?', 'Jigglymabob'] 
end 

Thing.create :name => 'Jigglymabob' 
# => #<Thing id: 1, name: "Jigglymabob"> 
w = Widget.create :name => 'Wookeleywoo', :thing_id => 1 
# => #<Widget id: 1, name: "Wookeleywoo", thing_id: 1> 
w.thing 
# => #<Thing id: 1, name: "Jigglymabob"> 

這一切後,我的日誌文件中包含:

Thing Create (0.3ms) INSERT INTO "things" ("name") VALUES('Jigglymabob') 
Widget Create (0.3ms) INSERT INTO "widgets" ("name", "thing_id") VALUES('Wookeleywoo', 1) 
Thing Load (0.6ms) SELECT * FROM "things" WHERE ("things"."id" = 1 AND (name = 'Jigglymabob')) 

正如我試圖和打字了你,我才意識到我仍然沒有真正回答你的問題。 :)我只能想到在ActiveRecord中有這樣的一個理由,那是因爲它沒有額外的實施麻煩,而且沒有任何好處。

有人在那裏可以工作在一個奇怪的邊緣情況與傳統數據庫中,在辦公室—是每個人都學會了艱辛的道路—的黃金法則是永遠不會有一個Wookeleywoo部件連接到除Jigglymabob其他任何東西。

+0

謝謝你,非常有幫助。 – 2010-01-28 20:15:04