ActiveRecord - 在一个连接中工作

时间:2012-08-08 08:58:31

标签: ruby-on-rails activerecord

例如,假设Rails 3.2.3中有代码

def test_action
  a = User.find_by_id(params[:user_id])
  # some calculations.....
  b = Reporst.find_by_name(params[:report_name])
  # some calculations.....
  c = Places.find_by_name(params[:place_name])
end

此代码对数据库发出3个请求,并打开3个不同的连接。最有可能的是,这将是一个相当长的行动。

有没有办法只打开一个连接并在其中执行3个请求?或者我想控制自己使用哪个连接。

2 个答案:

答案 0 :(得分:1)

您可以查看ActiveRecord::ConnectionAdapters::ConnectionPool文档 此外,AR不会为每个模型/查询打开连接,它会重用现有连接。

[7] pry(main)> [Advertiser.connection,Agent.connection,ActiveRecord::Base.connection].map(&:object_id)
=> [70224441876100, 70224441876100, 70224441876100]

答案 1 :(得分:1)

您可能希望使用transaction括号进行括号:

  

事务是只有SQL语句的保护块   永久性的,如果他们都可以成为一个原子行动。经典   例如,两个帐户之间的转移,你只能有一个   如果撤回成功则存款,反之亦然。交易   强制执行数据库的完整性并防范数据   程序错误或数据库故障。所以基本上你应该使用   每当你有许多必须的语句时,事务块   一起执行或根本不执行。

def test_action
  User.transaction do
    a = User.find_by_id(params[:user_id])
    # some calculations.....
    b = Reporst.find_by_name(params[:report_name])
    # some calculations.....
    c = Places.find_by_name(params[:place_name])
  end
end

即使他们调用不同的模型,操作也会封装到对DB的一次调用中。虽然它是全有或全无。如果中间失败则整个胶囊失效。

  

虽然在某些Active Record上调用了事务类方法   class,事务块中的对象不一定都是   该类的实例。这是因为事务是按数据库进行的   连接,而不是每个模型。