我正在尝试检索上一个state_change
的客户列表to_state_id
等于type
参数的值(self.filter_by
)。
我已经定义了一个名为current_state
的方法来检索客户端的当前to_state
,但我不确定如何在查询中应用它。
我还尝试在查询中使用state_changes.last.to_state_id
但是失败了,因为它认为'last'是一个表,当它实际上是一个方法时。
我的关系如下。 client
有state_changes
个state_change
,from_state
有to_state
和class State < ActiveRecord::Base
has_many :from_states, class_name: 'StateChange', foreign_key: :from_state_id
has_many :to_states, class_name: 'StateChange', foreign_key: :to_state_id
end
class StateChange < ActiveRecord::Base
belongs_to :client
belongs_to :from_state, class_name: "State", foreign_key: :from_state_id
belongs_to :to_state, class_name: "State", foreign_key: :to_state_id
end
class Client < ActiveRecord::Base
has_many :state_changes
def current_state
state_changes.last.to_state
end
def self.filter_by(type)
# querying for clients which have a current_state with id equal to type
joins(:state_changes).where('state_changes.last.to_state_id=?', type)
end
end
。
{{1}}
我是ActiveRecord和ruby的新手,所以要温柔:)
答案 0 :(得分:1)
使用Rails查询可能很有可能,但考虑到您所采取的性能影响以及将其添加到其他查询的潜力,我建议您在某处缓存当前值。这里有几个选项......
1)您可以向客户端添加列,并在客户端状态更改时进行设置。您可以在state_change模型上执行此操作after_create
。
在迁移中
add_column :clients, :current_state_id, :integer
并指向当前状态的状态记录。
def self.filter_by(type)
where(:current_state => type )
end
2)或者,您可以向state_changes表添加current
布尔值,并在当前状态更改时进行设置。您可以在此处设置索引,并在客户端
has_one :current_state, -> { where(current: true) }, class_name => "StateChange"
这是将部分索引添加到布尔列的方法:
Adding an index on a boolean field
如果你这样做了,那你就这样查询:
def self.filter_by(type)
joins(:current_state).where(:state_changes { :to_state_id => type })
end
在你的情况下,我会选择#1。感觉当前的状态可能在客户端,你会使用它很多。