Rails,从 table 中删除列并将其委托给关联的 table 并在 where 子句中使用委托列

Rails, Drop column from table and delegate it to an associated table and use the delegated column within where clause

我目前正在开发一个产品,出于某些原因,我们决定从特定的 table 中销毁 email 列,然后将该列委托给关联的 table 使用活动记录委托方法

https://apidock.com/rails/Module/delegate

我的问题是要遵循什么方法来确保所有使用 email 列的 where 子句也被委托。因为把我们用过的地方都查一遍基本上需要很多时间table.where(dropped_column: value)

例子

class Station < ActiveRecord::Base
  has_one :contact
  delegate :email, to: :contact
end

class Contact < ActiveRecord::Base
  belongs_to :station
end

我知道可以将所有查询从 Station.where(email: value) 切换到 Station.joins(:contact).where('contacts.email': value),但这种方法会花费很长时间,而且 where 子句可以用许多不同的方式编写因此搜索代码源并更新所有代码不足以覆盖所有情况。

如果有人遇到类似情况并设法以节省我们时间和错误的方式解决,我将很高兴听到您采用的方法。

谢谢。

Rails 版本:'5.2.3'

what is the approach to follow in order to make sure that all the where clauses that uses the email column are also delegated as well

你不能"delegate" SQL 命令。您需要全部更新它们。

I know that it is possible to switch all the queries from Station.where(email: value) to Station.joins(:contact).where('contacts.email': value) but this approach will take very long

是的,这就是您需要做的,抱歉!

If anyone face a similar situation and managed to solved in way that saves us time and bugs I will be very glad to hear what are the approaches you followd.

删除列之前,您可以先这样做:

class Station < ActiveRecord::Base
  self.ignored_columns = ['email']

  has_one :contact
  delegate :email, to: :contact

  # ...
end

这样,您可以阻止应用程序访问该列,而无需实际将其从数据库中删除(如 'soft delete'),这样可以轻松恢复。

在分支上执行此操作,并将所有规格设为绿色。 (如果你的测试覆盖率好,你就大功告成了!但是如果你的覆盖率很差,部署后可能会出现错误...)

如果部署后出现问题,您可以恢复整个 PR,或者在推送修复时再次临时注释掉 ignored_columns

最后,一旦您的应用程序 运行 顺利且没有错误,请删除该列。