目的是什么: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文档声明 belongs_to上的:conditions选项将:

指定关联对象必须满足的条件才能包含为WHERE SQL片段,例如authorized = 1。

但是输出在select上没有显示WHERE子句,并且在任何情况下我都希望在belongs_to上这样的条件会阻止在INSERT而不是SELECT上保持该关系的开始。 这个选项似乎对belongs_to关联没有影响,除非我遗漏了什么。 该选项在has_many上有意义,我只是看不出它如何适用于belongs_to。

编辑:进一步的研究表明,您确实可以坚持违反条件的关联,但重新加载记录您无法检索关联的记录。

在如此定义的类上:

 class Widget  "Bloop", :foreign_key => :big_bloop_id, :conditions => ["big_bloop = ?", true] belongs_to :bloop, :conditions => ["big_bloop = ?", true] end 

…从控制台我们看到:

 >> bloop = Bloop.new => # >> widget = Widget.new => # >> widget.bloop = bloop => # >> widget.save! => true >> widget => # 

我联系了一个违反条件的bloop并保存了它。 关联将持久保存到db(请参阅上面最后一行中的bloop_id和big_bloop_id)。

 >> big_bloop = Bloop.new => # >> widget.big_bloop = big_bloop => # >> widget.save! => true >> widget => # 

同样的事情,不同的属性。

 >> widget.bloop => # >> widget.big_bloop => # 

两个无效的bloops都保留在内存中。

 >> widget.reload => # >> 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 => # 

对我来说似乎很奇怪,但你去了。

这是一个很好的发现!

我的第一个想法是,这可能只是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' # => # w = Widget.create :name => 'Wookeleywoo', :thing_id => 1 # => # w.thing # => # 

毕竟,我的日志文件包含:

 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之外的任何东西。