我想制作一个activerecord记录的副本,在流程中更改单个字段(除了id之外 )。 最简单的方法是什么?

我意识到我可以创建一个新记录,然后遍历每个字段,逐字段复制数据-但我认为必须有一种更简单的方法来执行此操作...

如:

 @newrecord=Record.copy(:id)  *perhaps?*

#1楼

您还可以检查act_as_inheritable gem。

“作为继承的行为是专门为Rails / ActiveRecord模型编写的Ruby Gem。它旨在与Self-Referential Association或具有共享可继承属性的父级的模型一起使用。这将使您继承任何属性或与父模型的关系。”

通过将acts_as_inheritable添加到模型中,您将可以访问以下方法:

Inherit_attributes

class Person < ActiveRecord::Baseacts_as_inheritable attributes: %w(favorite_color last_name soccer_team)# Associationsbelongs_to  :parent, class_name: 'Person'has_many    :children, class_name: 'Person', foreign_key: :parent_id
endparent = Person.create(last_name: 'Arango', soccer_team: 'Verdolaga', favorite_color:'Green')son = Person.create(parent: parent)
son.inherit_attributes
son.last_name # => Arango
son.soccer_team # => Verdolaga
son.favorite_color # => Green

Inherit_relations

class Person < ActiveRecord::Baseacts_as_inheritable associations: %w(pet)# Associationshas_one     :pet
endparent = Person.create(last_name: 'Arango')
parent_pet = Pet.create(person: parent, name: 'Mango', breed:'Golden Retriver')
parent_pet.inspect #=> #<Pet id: 1, person_id: 1, name: "Mango", breed: "Golden Retriver">son = Person.create(parent: parent)
son.inherit_relations
son.pet.inspect # => #<Pet id: 2, person_id: 2, name: "Mango", breed: "Golden Retriver">

希望这可以帮到你。


#2楼

简单的方法是:

#your rails >= 3.1 (i was done it with Rails 5.0.0.1)o = Model.find(id)# (Range).each do |item|(1..109).each do |item|new_record = o.dupnew_record.saveend

要么

# if your rails < 3.1o = Model.find(id)(1..109).each do |item|new_record = o.clonenew_record.saveend

#3楼

由于可能存在更多逻辑,因此在复制模型时,我建议创建一个新类,在其中处理所有需要的逻辑。 为了缓解这种情况,有一个宝石可以帮助您: clowne

根据他们的文档示例,对于用户模型:

class User < ActiveRecord::Base# create_table :users do |t|#  t.string :login#  t.string :email#  t.timestamps null: false# endhas_one :profilehas_many :posts
end

您创建克隆器类:

class UserCloner < Clowne::Cloneradapter :active_recordinclude_association :profile, clone_with: SpecialProfileClonerinclude_association :postsnullify :login# params here is an arbitrary Hash passed into clonerfinalize do |_source, record, params|record.email = params[:email]end
endclass SpecialProfileCloner < Clowne::Cloneradapter :active_recordnullify :name
end

然后使用它:

user = User.last
#=> <#User(login: 'clown', email: 'clown@circus.example.com')>cloned = UserCloner.call(user, email: 'fake@example.com')
cloned.persisted?
# => falsecloned.save!
cloned.login
# => nil
cloned.email
# => "fake@example.com"# associations:
cloned.posts.count == user.posts.count
# => true
cloned.profile.name
# => nil

从项目中复制了示例,但是它将清晰地说明您可以实现的目标。

为了快速而简单地记录,我将选择:

Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}


#4楼

这是重写ActiveRecord #dup方法的示例,以自定义实例复制并包括关系复制:

class Offer < ApplicationRecordhas_many :offer_itemsdef dupsuper.tap do |new_offer|# change title of the new instancenew_offer.title = "Copy of #{@offer.title}"# duplicate offer_items as wellself.offer_items.each { |offer_item| new_offer.offer_items << offer_item.dup }endend
end

注意:此方法不需要任何外部gem,但需要使用#dup实现#dup方法的较新ActiveRecord版本


#5楼

在Rails 5中,您可以像这样简单地创建重复的对象或记录。

new_user = old_user.dup

#6楼

要获得副本,请使用clone(对于rails则为dup)3.1:

# rails < 3.1
new_record = old_record.clone#rails >= 3.1
new_record = old_record.dup

然后,您可以更改所需的任何字段。

ActiveRecord会覆盖内置的Object#clone,从而为您提供一个具有未分配ID的新记录(未保存到DB)。
请注意,它不会复制关联,因此如果需要,您将必须手动执行此操作。

Rails 3.1 clone是一个浅表副本,请改用dup ...


#7楼

我通常只是复制属性,更改我需要更改的内容:

new_user = User.new(old_user.attributes.merge(:login => "newlogin"))

#8楼

根据您的需求和编程风格,您还可以结合使用类的新方法和合并。 由于缺少更好的简单示例,假设您已将任务安排在某个日期,并且您想将其复制到另一个日期。 任务的实际属性并不重要,因此:

old_task = Task.find(task_id)
new_task = Task.new(old_task.attributes.merge({:scheduled_on => some_new_date}))

将使用:id => nil:scheduled_on => some_new_date以及所有其他属性与原始任务创建一个新任务。 使用Task.new,您将必须显式调用save,因此,如果要自动保存,请将Task.new更改为Task.create。

和平。


#9楼

如果您不想复制ID,请使用ActiveRecord :: Base#dup


#10楼

如果您需要具有关联的深层副本,建议使用deep_cloneable gem。


#11楼

您可能还喜欢ActiveRecord 3.2的变形虫 。

在您的情况下,您可能想利用配置DSL中可用的nullifyregexprefix选项。

它支持has_onehas_manyhas_and_belongs_to_many关联的轻松,自动的递归复制,字段预处理和高度灵活且功能强大的配置DSL,可同时应用于模型和运行中。

一定要检查变形虫文档,但用法非常简单...

只是

gem install amoeba

或添加

gem 'amoeba'

到您的Gemfile

然后将变形虫块添加到模型中,并照常运行dup方法

class Post < ActiveRecord::Basehas_many :commentshas_and_belongs_to_many :tagsamoeba doenableend
endclass Comment < ActiveRecord::Basebelongs_to :post
endclass Tag < ActiveRecord::Basehas_and_belongs_to_many :posts
endclass PostsController < ActionControllerdef some_methodmy_post = Post.find(params[:id])new_post = my_post.dupnew_post.saveend
end

您还可以控制通过多种方式复制哪些字段,但是,例如,如果要防止重复注释,但又想保留相同的标签,则可以执行以下操作:

class Post < ActiveRecord::Basehas_many :commentshas_and_belongs_to_many :tagsamoeba doexclude_field :commentsend
end

您还可以预处理字段,以帮助使用前缀和后缀以及正则表达式来指示唯一性。 此外,还有许多选项,因此您可以根据自己的目的以最易读的方式编写:

class Post < ActiveRecord::Basehas_many :commentshas_and_belongs_to_many :tagsamoeba doinclude_field :tagsprepend :title => "Copy of "append :contents => " (copied version)"regex :contents => {:replace => /dog/, :with => "cat"}end
end

关联的递归复制很容易,也只需在子模型上启用变形虫

class Post < ActiveRecord::Basehas_many :commentsamoeba doenableend
endclass Comment < ActiveRecord::Basebelongs_to :posthas_many :ratingsamoeba doenableend
endclass Rating < ActiveRecord::Basebelongs_to :comment
end

配置DSL还有更多选项,因此请务必查看文档。

请享用! :)

复制活动记录记录的最简单方法是什么?相关推荐

  1. 学科实践活动感悟50字_学科实践活动写实记录50字范文

    很多同学都需要写学科实践活动的记录,那么学科实践记录应该怎么写?大家一起来看看吧. 学科实践记录范文 孔子云:"知之者不如好之者,好之者不如乐之者."学生语文能力的发展很大程度上决 ...

  2. IDL学习记录和Java调用IDL方法

    IDL学习记录和Java调用IDL方法 2018年02月06日 08:32:02 回首1949 阅读数:385更多 个人分类: 随想 版权声明:乐呵乐呵得了 https://blog.csdn.net ...

  3. 记录微信小程序createIntersectionObserver()方法的使用

    最近做的微信小程序项目涉及到了曝光埋点需求,即页面上某一模块或者某一些模块被滑动显示在屏幕上的时候,需要做相关的埋点记录,想到了之前用过小程序提供的createIntersectionObserver ...

  4. vue 商城浏览足迹_vue 移动端记录页面浏览位置的方法

    记录一下本次项目我使用的方法,有更简单便捷的方法,欢迎交流 描述: 假设有a b c 页面 从a页面 到 b页面 ,b页面到c页面 b到c页面的时候需要记录当前b的浏览位置,c返回到b的时候滚动到上次 ...

  5. Centos7.9上利用cephadm安装Ceph Octopus 15.2的采坑记录,附带K8S挂载方法

    Centos7.9上利用cephadm安装Ceph Octopus 15.2的采坑记录,附带K8S挂载方法 0.亮点 1 准备 1.1 修改历史记录 1.2 升级系统内核 1.3 配置免密登录 问题1 ...

  6. u盘使用记录、痕迹删除技巧方法

    在日常生活的使用U盘过程当中,系统会记录下大量U盘的使用记录信息,那么接下来小编就来同大家分享介绍如何删除掉这些使用记录的方法知识. 1. 往系统里面添加环境变量devmgr_shownonprese ...

  7. Windows Server查看和记录远程登录信息的方法

    前两天我的一台Windows Server 2012R2的服务器中了传说中的cryptowall病毒,所有数据文件都被加密,需要我支付1个比特币才能解码.幸好服务器上没什么重要的文件,还好我没钱,我选 ...

  8. java exception 行号_java日志记录错误的文件_方法_行号_报错信息

    1.java日志记录错误的文件.方法.行号.报错信息 StackTraceElement s= e.getStackTrace()[0]; 1.1.记录保存的文件s.getFileName() 1.2 ...

  9. 【踩坑记录】mybatis-plus的insert方法,默认会生成一个uuid作为主键,导致类型不一致,存入数据库报错

    [踩坑记录]mybatis-plus的insert方法,默认会生成一个uuid作为主键,导致类型不一致,存入数据库报错 报错记录 解决方案 推荐方案 使用uuid作为主键,修改id的类型为bigint ...

  10. 警告: 程序集绑定日志记录被关闭。解决方法

    警告: 程序集绑定日志记录被关闭.解决方法 参考文章: (1)警告: 程序集绑定日志记录被关闭.解决方法 (2)https://www.cnblogs.com/zglyzi/p/3288158.htm ...

最新文章

  1. 创建maven项目但是总是报错
  2. Spring核心AOP(面向切面编程)
  3. exchange2003防垃圾邮件设置
  4. devi into python 笔记(一)字典 列表的简单操作
  5. 【Python】 获取MP3信息replica
  6. 成绩不超过100的C语言,输入若干个学生的百分制成绩,计算平均分并输出.输入-1表示结束,若输入的成绩超过100,则需重新输入.c语言...
  7. css3实现超出文本指定行数(指定文本长度)用省略号代替
  8. NVIDIA开源了基于PyTorch的3D深度学习的综合库
  9. Icicle is not a symbol o chillness but a sign of warming.
  10. Linux MTD子系统 _从模型分析到Flash驱动模板
  11. LRU的两种实现方案
  12. Android 安全(1)---概述
  13. mysql中索引创建 查看和删除语句_MySQL索引的创建、删除和查看(学习中)
  14. 仿照vue实现简易的MVVM框架(二)
  15. Bailian2930 加减乘除【水题】
  16. sql 最外层传值给最内层查询_腾讯云高级工程师如何玩转PG查询处理与执行器算法...
  17. 成功激活windows server 2008 sp2!
  18. 商务周刊:手机新三国演义
  19. JavaScript -- Map数据结构
  20. 刀图案c语言,刀符号图案大全 | 手游网游页游攻略大全

热门文章

  1. NIO框架之MINA详解
  2. 客户端发送消息时,源码运行的大致流程
  3. 数据如何写入到HBase
  4. 开启Thread线程只执行一次
  5. java gui 项目解密,java GUI(实例小项目--列出磁盘目录)
  6. python转cython_用Cython加速Python到“起飞”(推荐)
  7. 程序与进程的区别,并发与并行的区别,多进程的实现原理
  8. 创新课程管理系统数据库设计心得
  9. python 自带的range是不能实现对小数的操作的,如果要对小数操作可以使用numpy...
  10. 2018牛客网暑假ACM多校训练赛(第二场)E tree 动态规划