Я хочу сделать копию записи активной записи, меняя одно поле в процессе (в дополнение к идентификатору ). Какой самый простой способ сделать это?
Я понимаю, что могу создать новую запись, а затем перебрать каждое из полей, копируя данные поле за полем - но я подумал, что должен быть более простой способ сделать это ...
такие как:
@newrecord=Record.copy(:id) *perhaps?*
источник
q = p.clone
, и тогдаp == q
яtrue
вернусь. С другой стороны, если я используюq = p.dup
, яfalse
возвращаюсь при сравнении их.new?
метод не работает.В зависимости от ваших потребностей и стиля программирования вы также можете использовать комбинацию нового метода класса и слияния. Ввиду отсутствия более простого примера, предположим, что у вас есть задача, запланированная на определенную дату, и вы хотите дублировать ее на другую дату. Фактические атрибуты задачи не важны, поэтому:
создаст новую задачу с
:id => nil
,:scheduled_on => some_new_date
и все другие атрибуты будут такими же, как и исходная задача. Используя Task.new, вам придется явно вызывать функцию save, поэтому, если вы хотите, чтобы она сохранялась автоматически, измените Task.new на Task.create.Мир.
источник
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
Вам также может понравиться драгоценный камень Amoeba для ActiveRecord 3.2.
В вашем случае, вы , вероятно , хотите, чтобы использовать
nullify
,regex
илиprefix
опций , доступных в DSL конфигурации.Он поддерживает простое и автоматическое рекурсивное дублирование
has_one
,has_many
иhas_and_belongs_to_many
ассоциацию, поле предварительной обработку и очень гибкую и мощную конфигурацию DSL , которые могут быть применены как к модели и на лета.Обязательно ознакомьтесь с документацией Amoeba, но ее использование довольно просто ...
просто
или добавить
в ваш Gemfile
затем добавьте блок амебы в вашу модель и запустите
dup
метод как обычноВы также можете контролировать, какие поля копируются различными способами, но, например, если вы хотите предотвратить дублирование комментариев, но хотите сохранить те же теги, вы можете сделать что-то вроде этого:
Вы также можете предварительно обработать поля, чтобы помочь указать уникальность как с префиксами и суффиксами, так и с регулярными выражениями. Кроме того, есть также множество опций, поэтому вы можете писать в наиболее удобном для вас стиле:
Рекурсивное копирование ассоциаций легко, просто включите амебу на дочерних моделях.
Конфигурационный DSL имеет еще больше опций, поэтому обязательно ознакомьтесь с документацией.
Наслаждайтесь! :)
источник
.amoeba_dup
не только.dup
. Я пытался выполнить этот код, но он не работал здесь.Используйте ActiveRecord :: Base # dup, если вы не хотите копировать идентификатор
источник
.clone
Я обычно просто копирую атрибуты, меняя все, что мне нужно:
источник
unknown attribute
ошибку с одним столбцом из-за столбца, который существует из-за отношения has_many. Есть ли способ обойти это?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Это сохранит нового пользователя с правильным уникальным идентификатором.Если вам нужна глубокая копия с ассоциациями, я рекомендую гем deep_cloneable .
источник
В Rails 5 вы можете просто создать дублированный объект или запись, подобную этой.
источник
Самый простой способ:
Или
источник
Вот пример переопределения
#dup
метода ActiveRecord для настройки дублирования экземпляра и включения дублирования отношений:Примечание: этот метод не требует внешнего гема, но требует более новой версии ActiveRecord с
#dup
реализованным методомисточник
Вы также можете проверить драгоценный камень act_as_inheritable .
«Acts As Inheritable - это Ruby Gem, специально созданный для моделей Rails / ActiveRecord. Он предназначен для использования с само-ссылочной ассоциацией или с моделью, имеющей родителя, который разделяет наследуемые атрибуты. Это позволит вам наследовать любой атрибут или отношение от родительской модели ".
Добавляя
acts_as_inheritable
к своим моделям, вы будете иметь доступ к этим методам:inherit_attributes
inherit_relations
Надеюсь, это поможет вам.
источник
Поскольку при дублировании модели может быть больше логики, я бы предложил создать новый класс, в котором вы обрабатываете всю необходимую логику. Чтобы облегчить это, есть драгоценный камень, который может помочь: клоун
В соответствии с их примерами документации для модели User:
Вы создаете свой класс клонеров:
и затем используйте это:
Пример скопирован из проекта, но он даст четкое представление о том, чего можно достичь.
Для быстрой и простой записи я бы пошел с:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
источник