简体   繁体   English

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

[英]Rails - what is the most efficient way to create record or update it (if the record exists)?

I have a MySQL relation with 3 primary keys called golden_results : platform_id, release_id, configuration_id 我有一个与3个主键的MySQL关系,这些键称为golden_resultsplatform_id, release_id, configuration_id

All of those are also foreign keys to other relations. 所有这些都是其他关系的外键。

Now, I also have a rake task than scans every week or so the options, and fills this relation with proper information. 现在,我还有一个瑞克任务,而不是每周扫描大约一个选项,并用适当的信息填充这种关系。

There are two cases: 有两种情况:

  1. the record with this three-some-key already exists: in this case I would like to update the current record with refreshed data. 具有三个键的记录已经存在:在这种情况下,我想用刷新的数据更新当前记录。 I've read that there once was a create_or_update method which isn't exists now. 我读过,曾经有一个create_or_update方法现在不存在。

  2. the record doesn't exists: in this case I'd like to add this record with the data. 该记录不存在:在这种情况下,我想将此记录与数据一起添加。

As this may be a big access to the DB, the ideal way to achieve this would be to insert the records as transaction . 由于这可能是对DB的大量访问,因此实现此目的的理想方法是将记录作为transaction插入。 I've read this article which suggest the most proper way of achieving this from performance perspective. 我阅读了这篇文章 ,从性能的角度提出了实现此目标的最正确方法。

My current code looks like this (this, of course, isn't best solution as described...): 我当前的代码如下所示(当然,这不是所描述的最佳解决方案...):

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
    )

end 结束

Can anyone suggest a solution? 谁能提出解决方案? (hopefully one that doesn't asks me to write my own query, so that the rails convention will keep on being preserved using ActiveRecord). (希望它不会要求我编写自己的查询,这样,rails约定将继续使用ActiveRecord保留)。

BTW- I'm using Rails 4, with mysql2 driver. 顺便说一句,我正在使用带有MySQL2驱动程序的Rails 4。

Thanks! 谢谢!

Try find_or_create_by ( http://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by ). 尝试使用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

This is not an unusual problem: 这不是一个异常问题:

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

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

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