我想根据定义的属性为模型选择记录。
我有一个Docket模型。 Dockets有很多状态。 (我想记录每个状态更改以维护状态更改历史记录以及每个状态更改的一些元数据。)每个状态都有一个代码属性。
每个Docket都有一个已定义的属性:currentstatus(self.Statuses.last.code)。我想选择所有具有currentstatus == 1的Docket。因为它是一个已定义的属性,所以我不能使用Dockets.where(:currentstatus => 1)。
提前感谢您的帮助。
答案 0 :(得分:1)
您可以在docket.rb中使用 named_scope :
named_scope :find_by_currentstatus, lambda {|currentstatus|
{:conditions => {:currentstatus => 1}}
}
答案 1 :(得分:1)
你可以尝试一种SQL方法
Docket.where('(SELECT statuses.currentstatus FROM statuses WHERE statuses.docket_id = dockets.id ORDER BY statuses.created_at DESC LIMIT 1) = ?', 1)
答案 2 :(得分:0)
试试这个:
Docket.joins(:statuses).where("statuses.currentstatus = 1")
尝试以下方法:
Docket.includes(:statuses).where("(statuses.id = (select max(statuses2.id) from statuses statuses2 where statuses2.docket_id = dockets.id)) AND (statuses.currenstatus = 1)")
答案 3 :(得分:0)
这是一个棘手的问题,因为你只有两个非常丑陋的选择,而且有点笨拙:
a)加载所有内容并将其过滤到内存中(不要这样做!)
b)将current_status
方法中的逻辑转换为SQL查询,并在current_status
方法和search_for_current_status
方法中复制逻辑。
c)复制数据(意思是,当current_status更改时,您在Docket上设置了一个标记,然后您可以使用where
进行查询。
永远都不要 - 考虑b,如果current_status方法很简单(你可以在Docket模型的范围方法中定义它),这样就可以了。
class Docket < ActiveRecord::Base
def self.open
# so some magic here with joins on the statuses table
end
end
c基本上只是为了查询目的而对数据进行反规范化。你可以把它放到原始模型中,或者你可以创建一个特殊的表(你甚至可以通过cron-job或其他触发器自动刷新该表 - 也许是Status
模型中的ActiveRecord after_save回调)