目的是什么:条件属于一个人
假设我有以下与附加条件的关联:
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 < 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>
对我来说似乎很奇怪,但是你去了。
这是一个很好的发现!
我的第一个想法是,这可能只是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以外的任何其他部件。
链接地址: http://www.djcxy.com/p/44357.html