Chcę zrobić kopię rekordu activerecord, zmieniając pojedyncze pole w tym procesie (oprócz id ). Jaki jest najprostszy sposób na osiągnięcie tego?
Zdaję sobie sprawę, że mogę utworzyć nowy rekord, a następnie wykonać iterację po każdym polu kopiującym dane pole po polu - ale pomyślałem, że musi istnieć łatwiejszy sposób na zrobienie tego ...
Jak na przykład:
@newrecord=Record.copy(:id) *perhaps?*
q = p.clone
, a potemp == q
, mamtrue
powrotem. Z drugiej strony, jeśli użyjęq = p.dup
,false
wrócę podczas ich porównywania.new?
metoda nie działa.W zależności od potrzeb i stylu programowania możesz także użyć kombinacji nowej metody klasy i scalenia. Z braku lepszego prostego przykładu załóżmy, że masz zaplanowane zadanie na określoną datę i chcesz je zduplikować na inną datę. Rzeczywiste atrybuty zadania nie są ważne, więc:
utworzy nowe zadanie z
:id => nil
,:scheduled_on => some_new_date
i wszystkie inne atrybuty będą takie same jak pierwotne zadanie. Korzystając z Task.new, będziesz musiał jawnie wywołać save, więc jeśli chcesz, aby zapisywał się automatycznie, zmień Task.new na Task.create.Pokój.
źródło
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
zwróconyMoże ci się spodobać klejnot Amoeba dla ActiveRecord 3.2.
W twoim przypadku, prawdopodobnie chcesz skorzystać z
nullify
,regex
lubprefix
opcji dostępnych w konfiguracji DSL.To pozwala na łatwe i automatyczne rekurencyjną powielania
has_one
,has_many
orazhas_and_belongs_to_many
stowarzyszenia, wstępne przetwarzanie pole i wysoce elastyczny i potężny DSL konfiguracji, które mogą być stosowane zarówno do modelu i na bieżąco.koniecznie sprawdź dokumentację Amoeba, ale korzystanie z niej jest dość łatwe ...
właśnie
lub dodaj
do twojego Gemfile
następnie dodaj blok ameby do swojego modelu i uruchom
dup
metodę jak zwykleMożesz także kontrolować, które pola są kopiowane na wiele sposobów, ale na przykład, jeśli chcesz zapobiec duplikowaniu komentarzy, ale chcesz zachować te same tagi, możesz zrobić coś takiego:
Możesz również wstępnie przetwarzać pola, aby pomóc wskazać unikalność zarówno przedrostków, jak i przyrostków, a także wyrażeń regularnych. Ponadto istnieje wiele opcji, dzięki którym możesz pisać w najbardziej czytelnym stylu:
Rekurencyjne kopiowanie skojarzeń jest łatwe, po prostu włącz amebę także w modelach potomnych
Konfiguracja DSL ma jeszcze więcej opcji, więc sprawdź dokumentację.
Cieszyć się! :)
źródło
.amoeba_dup
nie tylko.dup
. Próbowałem wykonać ten kod, ale tutaj nie działał.Użyj ActiveRecord :: Base # dup, jeśli nie chcesz kopiować identyfikatora
źródło
.clone
Zwykle po prostu kopiuję atrybuty, zmieniając wszystko, co muszę zmienić:
źródło
unknown attribute
pojawia się błąd w jednej kolumnie z powodu kolumny, która jest tam z powodu relacji has_many. Czy jest na to jakiś sposób?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Spowoduje to zapisanie nowego użytkownika z poprawnym unikalnym identyfikatorem.Jeśli potrzebujesz głębokiej kopii ze skojarzeniami, polecam klejnot deep_cloneable .
źródło
W Rails 5 możesz po prostu utworzyć duplikat obiektu lub nagrać w ten sposób.
źródło
Łatwy sposób to:
Lub
źródło
Oto próbka nadpisującej
#dup
metody ActiveRecord w celu dostosowania duplikacji instancji i uwzględnienia również duplikacji relacji:Uwaga: ta metoda nie wymaga zewnętrznego klejnotu, ale wymaga nowszej wersji ActiveRecord z
#dup
zaimplementowaną metodąźródło
Możesz także sprawdzić klejnot act_as_inheritable .
„Działa jako dziedziczny to rubinowy klejnot napisany specjalnie dla modeli Rails / ActiveRecord. Jest przeznaczony do użycia z powiązaniem samo-referencyjnym lub z modelem posiadającym rodzica, który ma wspólne atrybuty dziedziczne. Pozwoli ci to odziedziczyć dowolny atrybut lub relacja z modelu nadrzędnego ”.
Dodając
acts_as_inheritable
do swoich modeli będziesz miał dostęp do tych metod:inherit_attributes
inherit_relations
Mam nadzieję, że to może ci pomóc.
źródło
Ponieważ może istnieć więcej logiki, przy powielaniu modelu sugerowałbym utworzenie nowej klasy, w której obsłużysz całą potrzebną logikę. Aby to ułatwić, istnieje klejnot, który może pomóc: clowne
Zgodnie z przykładami dokumentacji dla modelu użytkownika:
Tworzysz klasę klonera:
a następnie użyj go:
Przykład skopiowany z projektu, ale da jasną wizję tego, co możesz osiągnąć.
Dla szybkiego i prostego zapisu wybrałbym:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
źródło