我在关联中使用了find_by:
“sub”与“main”具有多对一的关系
@main.subs.find_by(x: 123)
在大多数情况下,我希望它使用常规选择从数据库中访问和检索与“main”相关的“子”记录:
select subs.* from subs where subs.main_id = 333 and subs.x = 123
但还有另一个场景,我希望它忽略数据库并访问我在“main”下创建的“subs”的存根:
stub_sub = Sub.new(id: 22, x: 123, main_id: 333)
@main.subs << stub_sub
@main也没有保存在数据库中,而是像sub:
一样创建@main = Main.new(id: 333)
当我在调试时到达find_by行,并尝试访问@main.subs时,它看起来就像我从db查询得到的活动记录关系,但如果我做了像find_by / all这样的事情,它会尝试访问数据库并看到那里没有任何内容并返回空关系。
有没有办法阻止find_by(或任何活动的记录方法)访问数据库,只是处理我为它创建的存根关系?
答案 0 :(得分:0)
I think there are a few misunderstandings in your question there. Firstly, the find_by
method does not return all matching records but just the first one, you probably wanted to use the where
method instead.
Secondly, the <<
operator on a has_many
association actually saves the association record so a where
query should return it perfectly after assigning the association, i.e. just after calling <<
.
Update: If the main object does not yet exist in the database either, then indeed the <<
operator does not save anything. In that case, the only solution that comes to my mind is to give up ActiveRecord methods (such as find_by
or where
) because they always try to query the db to get the information and to search for the matching associated record manually instead.
So instead of @main.subs.where(x: 123)
you would do:
@main.subs.to_a.select { |sub| sub.x == 123 }
This way, you will load all attached associations first, including the newly attached and unsaved ones and then filter them using a ruby condition against their attributes.
The big disadvantage of this is however that when using this code with a saved record, you will always load all its associated records, not only those which match the condition. Thus, if you had a record with a lot of associated records, you'd be killing the performance of such filtering.