在连接表的ActiveRecord查询中应用方法

时间:2016-11-21 21:40:12

标签: ruby-on-rails ruby activerecord rails-activerecord

我正在尝试检索上一个state_change的客户列表to_state_id等于type参数的值(self.filter_by)。

我已经定义了一个名为current_state的方法来检索客户端的当前to_state,但我不确定如何在查询中应用它。 我还尝试在查询中使用state_changes.last.to_state_id但是失败了,因为它认为'last'是一个表,当它实际上是一个方法时。

我的关系如下。 clientstate_changesstate_changefrom_stateto_stateclass 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的新手,所以要温柔:)

1 个答案:

答案 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
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。感觉当前的状态可能在客户端,你会使用它很多。