使用find_or_initialize_by_ticker时接收数据库错误

时间:2016-10-11 07:56:42

标签: ruby-on-rails

我正在运行一个关联find_or_initialize_by_ticker方法并继续接收

PG::InFailedSqlTransaction: ERROR:  current transaction is aborted,
commands ignored until end of transaction block

我的头寸有一个stock_id属性,我想检查一下我的任何仓位是否存在特定的股票对象。

如果库存对象已经存在,那么我可以抓住它,如果没有,将创建一个新位置,我可以使用该对象。

我正在考虑使用像

这样的关联扩展来编写自己的方法
has_many :positions do
  def find_or_initialize_by_ticker(ticker)
    position_with_ticker = self.select do |position|
      position.stock['symbol'] == ticker
    end
    if position_with_ticker
      position_with_ticker.first
    else
      Position.new
    end
  end
end

这是找到职位的最有效方式吗?

1 个答案:

答案 0 :(得分:0)

您可以使用ActiveRecord的内置#first_or_initialize吗?

它已经为您构建了,并且对数据库进行过滤要快得多,而不是返回所有行,然后使用select手动过滤它们(更少的数据要传输) )。

您如何使用它取决于您如何定义stock变量:

股票是另一张表

my_model.positions
        .joins(:stock)
        .where(stock: { symbol: ticker })
        .first_or_initialize

Stock是Postgres JSON或HSTORE字段

来自Active Record and PostgreSQL

# see docs for -> vs ->>
my_model.positions
        .where("stock->>'symbol' = ?", ticker)
        .first_or_initialize