Rails - 创建记录或更新记录(如果记录存在)的最有效方法是什么?

时间:2014-10-10 13:26:26

标签: mysql ruby-on-rails ruby activerecord

我与3个主键有一个MySQL关系,名为 golden_results platform_id, release_id, configuration_id

所有这些都是其他关系的外键。

现在,我还有一个rake任务,而不是每周扫描选项,并用适当的信息填充这种关系。

有两种情况:

  1. 这个三键的记录已经存在:在这种情况下,我想用刷新的数据更新当前记录。我读过曾经有一个create_or_update方法现在不存在。

  2. 记录不存在:在这种情况下,我想将此记录与数据一起添加。

  3. 由于这可能是对数据库的大访问,实现此目标的理想方法是将记录插入事务。 我已经阅读了this article,它提出了从绩效角度实现这一目标的最恰当方式。

    我当前的代码看起来像这样(当然,这不是所描述的最佳解决方案......):

    def add_golden_result record
    
    response= 
        GoldenResult.find_or_create_by(platform_id: record.platform_id, release_id: record.release_id, configuration_id: record.configuration_id) do |r|
            r.asr_ndr_bandwidth         =   record.asr_ndr_bandwidth
            r.normalized_ndr_bandwidth  =   record.asr_ndr_bandwidth/(10.0*record.ndr_cpu)
            r.asr_latency_bandwidth     =   record.asr_latency_bandwidth
        end
    
    response.update(
        asr_ndr_bandwidth: record.asr_ndr_bandwidth, 
        normalized_ndr_bandwidth: record.asr_ndr_bandwidth/(10.0*record.ndr_cpu),
        asr_latency_bandwidth: record.asr_latency_bandwidth
        )
    

    有人可以提出解决方案吗? (希望有一个不要求我编写自己的查询,以便使用ActiveRecord保持rails约定。)

    BTW-我正在使用Rails 4,带有mysql2驱动程序。

    谢谢!

2 个答案:

答案 0 :(得分:2)

尝试find_or_create_byhttp://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by)。

record = GoldenResult.find_or_create_by( platform_id: platform_id, 
         release_id: release_id, configuration_id: configuration_id ) do |record|
  # fill in additional data for a new record if needed
end

答案 1 :(得分:0)

这不是一个不寻常的问题:

ClassName.find_or_create_by(foo: "foo", bar: "bar", f_b_id: 1).tap do |record|
  # This runs the code on ether the found or created record
  # #tap forces a block to be ran. 
  # The object of the block is the object that it's called on.
  record.other_field = "other data"
  record.even_more_data = "even more data"
  record.save
end