简体   繁体   English

如何使用around_action包装每个Rails ActiveRecord查询

[英]How to wrap every Rails ActiveRecord query using an around_action

I would like to create a module that when included, makes every active record query execute as a block that I will wrap. 我想创建一个模块,当包含该模块时,使每个活动记录查询都作为要包装的块执行。

Specifically I'm using https://github.com/zendesk/active_record_shards to shard to multiple databases. 具体来说,我正在使用https://github.com/zendesk/active_record_shards分片到多个数据库。 In this scenario we have 10 duplicate databases (same schema but different client instances) and 1 unique database. 在这种情况下,我们有10个重复的数据库(相同的架构,但不同的客户端实例)和1个唯一的数据库。 By default, any calls to our models that belong to the 10 duplicate databases will be wrapped in an application controller around_action that does 默认情况下,对属于10个重复数据库的模型的任何调用都将包装在应用程序控制器around_action中,

ActiveRecord::Base.on_shard(database_name) do
  yield
end 

However we have a set of models that should only execute queries against this 1 unique database. 但是,我们有一组模型只能对这个1个唯一的数据库执行查询。 Rather than execute every ActiveRecord query on those models using something like 而不是使用类似的方法在这些模型上执行每个ActiveRecord查询

ActiveRecord::Base.on_shard('unique_db') { Model.find(id) }

I would rather make a module that when included executes the active record query as a block inside the on_shard method so they always execute agains the unique_db 我宁愿创建一个模块,使其在on_shard方法内部作为一个块执行活动记录查询,因此它们总是再次执行unique_db

Let me know if I'm going down the wrong path and should just stick with my helper method which basically just shortens the length 让我知道我是否走错了路,应该坚持使用我的辅助方法,这基本上会缩短长度

module UniqeDB
  def self.exec!
    ActiveRecord::Base.on_shard('unique_db') do
      yield
    end
  end
end

Thanks! 谢谢!

Update: I was able to do something like this, however it overrides every method with (*args, &block) however some methods (like default_scope) only take a block and then it throws exceptions 更新:我能够做这样的事情,但是它用(* args,&block)覆盖了每个方法,但是某些方法(例如default_scope)仅接受一个块,然后抛出异常

included do
  ActiveRecord::Base.methods.each do |name|
    define_singleton_method name do |*args, &block|
      ActiveRecord::Base.on_shard('unique_db') do
        super(*args, &block)
      end
    end
  end
end

Update: I opened an issue with the gem to see if there is something i'm missing https://github.com/zendesk/active_record_shards/issues/87 更新:我打开了一个关于宝石的问题,看是否有我缺少的东西https://github.com/zendesk/active_record_shards/issues/87

Include the below module in any controller like ' include ExecuteInUniqueDB ' 将以下模块包含在任何控制器中,例如“ include ExecuteInUniqueDB

All action inside the controller will only in unique_db 控制器内部的所有动作将仅在unique_db中

module ExecuteInUniqueDB
  def self.included(base)
    base.class_eval do
      around_action :run_on_unique_db
    end
  end

  def run_on_unique_db(&block)
    ActiveRecord::Base.on_shard('unique_db', &block)
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM