การโคลนวัตถุ active_record อย่างง่ายดาย รวมถึงการเชื่อมโยงและการดำเนินการหลายอย่างภายใต้การเชื่อมโยงและคุณลักษณะ
ดูที่นี่
เป้าหมายคือเพื่อให้สามารถทำซ้ำออบเจ็กต์ ActiveRecord ได้อย่างง่ายดายและรวดเร็ว รวมถึงลูก ๆ ของพวกเขาด้วย เช่น การคัดลอกโพสต์ในบล็อกที่คงแท็กหรือหมวดหมู่ที่เกี่ยวข้องไว้
อัญมณีชนิดนี้มีชื่อว่า "อะมีบา" เพราะอะมีบา (สิ่งมีชีวิตขนาดเล็ก) สืบพันธุ์ได้ดี ลูกๆหลานๆของพวกเขายังสืบพันธุ์ตัวเองได้อย่างรวดเร็วและง่ายดาย
Gem ส่วนขยาย ActiveRecord เพื่ออนุญาตการทำซ้ำของวัตถุบันทึกลูกที่เกี่ยวข้องเมื่อทำซ้ำแบบจำลองบันทึกที่ใช้งานอยู่
รองรับ Rails 5.2, 6.0, 6.1 สำหรับ Rails 4.2 ถึง 5.1 ให้ใช้เวอร์ชัน 3.x
รองรับประเภทการเชื่อมโยงต่อไปนี้
has_many
has_one :through
has_many :through
has_and_belongs_to_many
DSL อย่างง่ายสำหรับการกำหนดค่าฟิลด์ที่จะคัดลอก สามารถใช้ DSL กับรางรุ่นของคุณหรือใช้งานได้ทันที
รองรับลูก STI (การสืบทอดตารางเดี่ยว) ที่สืบทอดการตั้งค่าอะมีบาของผู้ปกครอง
รูปแบบการกำหนดค่าที่หลากหลาย เช่น ครอบคลุม พิเศษ และไม่เลือกปฏิบัติ (หรือที่เรียกว่า คัดลอกทุกอย่าง)
รองรับการโคลนรายการย่อยของบันทึกแบบกลุ่มต่อกลุ่มหรือเพียงรักษาการเชื่อมโยงดั้งเดิมไว้
รองรับการเจาะลึกอัตโนมัติ เช่น การคัดลอกบันทึกลูกและหลานแบบเรียกซ้ำ
รองรับการประมวลผลฟิลด์ล่วงหน้าเพื่อช่วยระบุเอกลักษณ์และรับรองความสมบูรณ์ของข้อมูลของคุณ ขึ้นอยู่กับความต้องการตรรกะทางธุรกิจของคุณ เช่น นำหน้า "สำเนาของ" หรือข้อความที่คล้ายกัน
รองรับการประมวลผลล่วงหน้าของฟิลด์ด้วยบล็อก lambda แบบกำหนดเอง ดังนั้นคุณจึงสามารถทำทุกอย่างที่คุณต้องการได้โดยทั่วไป เช่น หากคุณต้องการตรรกะแบบกำหนดเองขณะทำสำเนา
อะมีบาสามารถดำเนินการประมวลผลล่วงหน้าต่อไปนี้ในฟิลด์ของบันทึกที่คัดลอก
ชุด
เติมหน้า
ผนวก
ทำให้เป็นโมฆะ
ปรับแต่ง
นิพจน์ทั่วไป
หวังว่าจะเป็นอย่างที่คุณคาดหวัง:
อัญมณีติดตั้งอะมีบา
หรือเพียงเพิ่มลงใน Gemfile ของคุณ:
อัญมณี 'อะมีบา'
กำหนดค่าโมเดลของคุณด้วยสไตล์ใดสไตล์หนึ่งด้านล่าง จากนั้นเพียงเรียกใช้เมธอด amoeba_dup
บนโมเดลของคุณ โดยที่คุณจะเรียกใช้เมธอด dup
ตามปกติ:
p = Post.create(:title => "Hello World!", :content => "Lorum ipsum dolor")p.comments.create(:content => "ฉันชอบมัน!")p.comments.create(: content => "นี่มันห่วย!") ทำให้ Comment.all.count # ควรเป็น 2my_copy = p.amoeba_dupmy_copy.saveputs Comment.all.count # ควรเป็น 4
ตามค่าเริ่มต้น เมื่อเปิดใช้งาน อะมีบาจะคัดลอกเรกคอร์ดย่อยที่เกี่ยวข้องทั้งหมดโดยอัตโนมัติ และเชื่อมโยงกับเรกคอร์ดหลักใหม่
คุณสามารถกำหนดค่าลักษณะการทำงานให้รวมเฉพาะฟิลด์ที่คุณแสดงรายการหรือรวมเฉพาะฟิลด์ที่คุณไม่ได้ยกเว้นได้ ในสามรูปแบบที่มีประสิทธิภาพมากที่สุดจะเป็นสไตล์ที่ไม่เลือกปฏิบัติ ตามมาด้วยสไตล์ที่ครอบคลุม และสไตล์พิเศษจะช้าที่สุดเนื่องจากจำเป็นต้องตรวจสอบอย่างชัดเจนเป็นพิเศษในแต่ละฟิลด์ ความแตกต่างของประสิทธิภาพนี้อาจไม่สำคัญพอที่จะทำให้คุณสามารถเลือกสไตล์ที่จะใช้โดยยึดตามรูปแบบที่อ่านและเขียนได้ง่ายที่สุด อย่างไรก็ตาม หากแผนผังข้อมูลของคุณมีขนาดใหญ่เพียงพอ และคุณต้องควบคุมว่าฟิลด์ใดจะถูกคัดลอก รูปแบบที่ครอบคลุมน่าจะดีกว่า ทางเลือกมากกว่าสไตล์พิเศษ
โปรดทราบว่าตัวอย่างเหล่านี้เป็นเพียงการประมาณอย่างหลวมๆ ของสถานการณ์ในโลกแห่งความเป็นจริงเท่านั้น และอาจไม่ได้สมจริงอย่างยิ่ง โดยมีวัตถุประสงค์เพื่อสาธิตการใช้งานฟีเจอร์เท่านั้น
นี่เป็นกรณีการใช้งานขั้นพื้นฐานที่สุด และจะเปิดใช้งานการคัดลอกการเชื่อมโยงที่รู้จักใดๆ
หากคุณมีโมเดลบางอย่างสำหรับบล็อกเกี่ยวกับสิ่งนี้:
คลาสโพสต์ < ActiveRecord::Base has_many :commentsendclass ความคิดเห็น < ActiveRecord::Base เป็นสมาชิก_to: postend
เพียงเพิ่มบล็อกการกำหนดค่าอะมีบาให้กับโมเดลของคุณและเรียกใช้เมธอด Enable เพื่อเปิดใช้งานการคัดลอกบันทึกลูก เช่นนี้
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น อะมีบาสามารถทำได้ ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
บันทึกลูกจะถูกคัดลอกโดยอัตโนมัติเมื่อคุณเรียกใช้เมธอด amoeba_dup
หากคุณต้องการคัดลอกการเชื่อมโยงบางส่วนเท่านั้น แต่ไม่ต้องการคัดลอกการเชื่อมโยงอื่นๆ คุณสามารถใช้รูปแบบที่ครอบคลุมได้:
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก has_many :ผู้เขียน อะมีบา doenableinclude_association :tagsinclude_association :authors ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
การใช้สไตล์รวมภายในบล็อกอะมีบาหมายความว่าคุณต้องการเปิดใช้งานอะมีบาจริง ๆ ดังนั้นจึงไม่จำเป็นต้องเรียกใช้เมธอด Enable ถึงแม้ว่ามันจะไม่เสียหายก็ตาม:
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก has_many :ผู้เขียน อะมีบา doinclude_association :tagsinclude_association :authors ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
คุณยังอาจระบุฟิลด์ที่จะคัดลอกโดยส่งอาร์เรย์ หากคุณเรียก include_association
ด้วยค่าเดียว ค่านั้นจะถูกผนวกเข้ากับรายการฟิลด์ที่รวมไว้แล้ว หากคุณส่งผ่านอาร์เรย์ อาร์เรย์ของคุณจะเขียนทับค่าดั้งเดิม
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก has_many :ผู้เขียน อะมีบา doinclude_association [:tags, :authors] ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
ตัวอย่างเหล่านี้จะคัดลอกแท็กของโพสต์และผู้เขียน แต่ไม่ใช่ความคิดเห็น
เมื่อใช้สไตล์แบบรวมจะปิดใช้งานสไตล์อื่นที่เลือกไว้ก่อนหน้านี้โดยอัตโนมัติ
หากคุณมีช่องข้อมูลมากกว่าที่จะรวม คุณอาจต้องการลดจำนวนการพิมพ์และการอ่านที่คุณต้องทำโดยใช้รูปแบบพิเศษ ฟิลด์ทั้งหมดที่ไม่ได้ยกเว้นอย่างชัดเจนจะถูกคัดลอก:
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก has_many :ผู้เขียน อะมีบา doexclude_association :ความคิดเห็น ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
ตัวอย่างนี้ทำสิ่งเดียวกับตัวอย่างสไตล์ที่ครอบคลุม โดยจะคัดลอกแท็กของโพสต์และผู้เขียน แต่ไม่ใช่ความคิดเห็น เช่นเดียวกับรูปแบบที่ครอบคลุม ไม่จำเป็นต้องเปิดใช้งานอะมีบาอย่างชัดเจนเมื่อระบุฟิลด์ที่จะยกเว้น
เมื่อใช้สไตล์เฉพาะตัวจะปิดใช้งานสไตล์อื่นๆ ที่เลือกไว้ก่อนหน้านี้โดยอัตโนมัติ ดังนั้นหากคุณเลือกช่องรวม แล้วคุณเลือกช่องที่ยกเว้นบางช่อง วิธี exclude_association
จะปิดใช้งานสไตล์รวมที่เลือกไว้ก่อนหน้านี้ และล้างช่องรวมที่เกี่ยวข้องใดๆ ออกไป .
นอกจากนี้ หากคุณต้องการกำหนดเส้นทางเงื่อนไขเพิ่มเติมสำหรับการรวมหรือแยกความสัมพันธ์ คุณสามารถกำหนดเส้นทางชื่อวิธีการไปที่ :if
ตัวเลือก
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก อะมีบา doinclude_association :ความคิดเห็น ถ้า: :ยอดนิยม? จบ ได้รับความนิยมอย่างแน่นอน?ไลค์ > 15 สิ้นสุด
หลังจากโทร Post.first.amoeba_dup
หาก likes
มากกว่า 15 ความคิดเห็นทั้งหมดจะถูกทำซ้ำเช่นกัน แต่ในสถานการณ์อื่น - ความสัมพันธ์จะไม่ถูกโคลน พฤติกรรมเดียวกันนี้มีไว้สำหรับ exclude_association
ระวัง ! หากคุณเขียนว่า:
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น has_many:แท็ก อะมีบา doexclude_association :tagsinclude_association :ความคิดเห็น ถ้า: :popular? จบ ได้รับความนิยมอย่างแน่นอน?ไลค์ > 15 สิ้นสุด
กลยุทธ์การรวมจะถูกเลือกโดยไม่คำนึงถึงผลลัพธ์ของ popular?
การเรียกเมธอด (เหมือนกันสำหรับสถานการณ์ย้อนกลับ)
หากคุณกำลังใช้ความสัมพันธ์แบบกลุ่มต่อกลุ่ม คุณอาจบอกให้อะมีบาทำสำเนาบันทึกที่เกี่ยวข้องกับต้นฉบับ แทนที่จะเพียงรักษาความเชื่อมโยงกับบันทึกต้นฉบับ การโคลนนิ่งเป็นเรื่องง่าย เพียงบอกอะมีบาว่าฟิลด์ใดที่จะโคลนในลักษณะเดียวกับที่คุณบอกว่าจะรวมหรือยกเว้นฟิลด์ใด
คลาสโพสต์ < ActiveRecord::Base has_and_belongs_to_many:คำเตือน has_many :post_widgets has_many :widgets, :through => :post_widgets อะมีบา doenableclone [:วิดเจ็ต, :คำเตือน] คำเตือน endendclass < ActiveRecord::Base has_and_belongs_to_many :postsendclass PostWidget < ActiveRecord::Base เป็นสมาชิก_to :widget อยู่ใน: postendclass Widget < ActiveRecord::Base has_many :post_widgets has_many :posts, :through => :post_widgetsend
ตัวอย่างนี้จะทำซ้ำคำเตือนและวิดเจ็ตในฐานข้อมูล หากเดิมมีคำเตือน 3 รายการในฐานข้อมูล เมื่อทำซ้ำโพสต์ คุณจะพบคำเตือน 6 รายการในฐานข้อมูล สิ่งนี้ตรงกันข้ามกับพฤติกรรมเริ่มต้นที่โพสต์ใหม่ของคุณจะถูกเชื่อมโยงใหม่กับคำเตือนที่มีอยู่ก่อนหน้านี้ และคำเตือนเหล่านั้นจะไม่ถูกทำซ้ำ
ตามค่าเริ่มต้น อะมีบาจะจดจำและพยายามคัดลอกรายการลูกของประเภทการเชื่อมโยงต่อไปนี้:
มีอันหนึ่ง
มีมากมาย
มีและเป็นของหลาย ๆ คน
คุณสามารถควบคุมว่าอะมีบาประเภทการเชื่อมโยงใดที่จะนำไปใช้กับตัวเองได้โดยใช้วิธี recognize
ภายในบล็อกการกำหนดค่าอะมีบา
คลาสโพสต์ < ActiveRecord::Base has_one :config has_many:ความคิดเห็น has_and_belongs_to_many :tags อะมีบา รู้จัก [:has_one, :has_and_belongs_to_many] ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน: postendclass แท็ก < ActiveRecord::Base has_and_belongs_to_many :postsend
ตัวอย่างนี้จะคัดลอกข้อมูลการกำหนดค่าของโพสต์และเก็บแท็กที่เกี่ยวข้องกับโพสต์ใหม่ แต่จะไม่คัดลอกความคิดเห็นของโพสต์ เนื่องจากอะมีบาจะจดจำและคัดลอกเฉพาะรายการย่อยของการเชื่อมโยง has_one
และ has_and_belongs_to_many
และในตัวอย่างนี้ ความคิดเห็นไม่ใช่การเชื่อมโยง has_and_belongs_to_many
หากคุณต้องการป้องกันไม่ให้ฟิลด์ปกติ (ไม่อิงการเชื่อมโยง has_*
) คงค่าของมันไว้เมื่อคัดลอก คุณอาจ "ลบออก" หรือ "ทำให้เป็นโมฆะ" ฟิลด์ได้ดังนี้:
หัวข้อคลาส < ActiveRecord::Base has_many :postsendclass โพสต์ < ActiveRecord::Base อยู่ใน:topic has_many:ความคิดเห็น อะมีบาทำได้เป็นโมฆะ :date_publishednullify :topic_id ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
ตัวอย่างนี้จะคัดลอกความคิดเห็นทั้งหมดของโพสต์ นอกจากนี้ยังจะทำให้วันที่เผยแพร่เป็นโมฆะและแยกโพสต์ออกจากหัวข้อเดิม
ต่างจากสไตล์แบบรวมและแบบเอกสิทธิ์เฉพาะบุคคล การระบุฟิลด์ว่างจะไม่ทำให้อะมีบาสามารถคัดลอกบันทึกย่อยทั้งหมดได้โดยอัตโนมัติ เช่นเดียวกับออบเจ็กต์บันทึกที่ใช้งานอยู่ ค่าฟิลด์เริ่มต้นจะถูกใช้แทน nil
หากมีค่าเริ่มต้นในการย้ายข้อมูล
หากคุณต้องการตั้งค่าฟิลด์ให้เป็นค่าที่กำหนดเองบนออบเจ็กต์ที่ซ้ำกันทั้งหมด คุณสามารถใช้คำสั่ง set
ได้ ตัวอย่างเช่น หากคุณต้องการคัดลอกออบเจ็กต์ที่มีกระบวนการอนุมัติบางประเภทที่เกี่ยวข้อง คุณอาจต้องการตั้งค่าสถานะของออบเจ็กต์ใหม่ให้เป็นเปิดหรือ "อยู่ระหว่างดำเนินการ" อีกครั้ง
คลาสโพสต์ < ActiveRecord::Base ปริมาณอะมีบา :state_tracker => "open_for_editing" สิ้นสุด
ในตัวอย่างนี้ เมื่อมีการทำซ้ำโพสต์ ฟิลด์ state_tracker
ของโพสต์นั้นจะได้รับค่า open_for_editing
เพื่อเริ่มต้นเสมอ
คุณสามารถเพิ่มสตริงที่จุดเริ่มต้นของฟิลด์ของวัตถุที่คัดลอกในระหว่างขั้นตอนการคัดลอก:
คลาสโพสต์ < ActiveRecord::Base อะมีบา doenableprepend :title => "สำเนาของ " สิ้นสุด
คุณสามารถเพิ่มสตริงที่ส่วนท้ายของฟิลด์ของวัตถุที่คัดลอกในระหว่างขั้นตอนการคัดลอก:
คลาสโพสต์ < ActiveRecord::Base อะมีบา doenableappend :title => "สำเนาของ " สิ้นสุด
คุณสามารถดำเนินการค้นหาและแทนที่แบบสอบถามในช่องของวัตถุที่คัดลอกในระหว่างขั้นตอนการคัดลอก:
คลาสโพสต์ < ActiveRecord::Base อะมีบา doenableregex :contents => {:replace => /dog/, :with => 'cat'} สิ้นสุด
คุณสามารถเรียกใช้วิธีการหรือวิธีการแบบกำหนดเองเพื่อทำสิ่งใดก็ได้ที่คุณต้องการ เพียงแค่ส่งบล็อก lambda หรืออาร์เรย์ของบล็อก lambda ไปยังคำสั่ง customize
แต่ละบล็อกจะต้องมีรูปแบบเดียวกัน ซึ่งหมายความว่าแต่ละบล็อกจะต้องยอมรับพารามิเตอร์สองตัว คือ ออบเจ็กต์ต้นฉบับและออบเจ็กต์ที่คัดลอกใหม่ จากนั้นคุณสามารถทำทุกอย่างที่คุณต้องการได้ดังนี้:
คลาสโพสต์ < ActiveRecord::Base อะมีบา doprepend :title => "Hello world! "customize(lambda { |Original_post,new_post| if original_post.foo == "bar"new_post.baz = "qux" end})append :comments => "... know what ฉันว่านะ?” สิ้นสุด
หรือสิ่งนี้โดยใช้อาร์เรย์:
คลาสโพสต์ < ActiveRecord::Base has_and_belongs_to_many :tags อะมีบา doinclude_association :tagscustomize([ lambda do |orig_obj,copy_of_obj|# good stuff going here end, lambda do |orig_obj,copy_of_obj|# more good stuff going here end]) สิ้นสุด
บล็อก Lambda ถูกส่งผ่านเพื่อปรับแต่งการทำงานตามค่าเริ่มต้น หลังจากการคัดลอกและการประมวลผลล่วงหน้าภาคสนามทั้งหมด หากคุณต้องการเรียกใช้เมธอดก่อนการปรับแต่งใดๆ หรือการประมวลผลล่วงหน้าของฟิลด์ คุณสามารถใช้ override
ลูกพี่ลูกน้องของ customize
การใช้งานก็เหมือนกับข้างบน
คลาสโพสต์ < ActiveRecord::Base อะมีบา doprepend :title => "สวัสดีชาวโลก! "override(lambda { |Original_post,new_post| if original_post.foo == "bar"new_post.baz = "qux" end})append :comments => "... know what ฉันว่านะ?” สิ้นสุด
คุณสามารถใช้ตัวประมวลผลล่วงหน้าตัวเดียวกับหลายฟิลด์พร้อมกันได้
คลาสโพสต์ < ActiveRecord::Base อะมีบา doenableprepend :title => "สำเนาของ ", :contents => "เนื้อหาที่คัดลอก: " สิ้นสุด
คุณสามารถใช้คำสั่งการประมวลผลล่วงหน้าหลายรายการกับโมเดลเดียวได้ในคราวเดียว
คลาสโพสต์ < ActiveRecord::Base อะมีบา doprepend :title => "สำเนาของ ", :contents => "เนื้อหาต้นฉบับ: "ผนวก :contents => " (เวอร์ชันที่คัดลอก)"regex :contents => {:replace => /dog/, :with => ' แมว'} สิ้นสุด
ตัวอย่างนี้ควรให้ผลลัพธ์ดังนี้:
โพสต์ = Post.create( :title => "สวัสดีชาวโลก", :contents => "ฉันชอบหมา หมามันเจ๋ง")new_post = post.amoeba_dupnew_post.title # "สำเนาของ Hello world"new_post.contents # "เนื้อหาต้นฉบับ: ฉันชอบแมว แมวมันเจ๋ง (ฉบับคัดลอก)"
เช่นเดียวกับ nullify
คำสั่งการประมวลผลล่วงหน้าจะไม่เปิดใช้งานการคัดลอกบันทึกลูกที่เกี่ยวข้องโดยอัตโนมัติ หากใช้คำสั่งการประมวลผลล่วงหน้าเท่านั้นและคุณต้องการคัดลอกเรคคอร์ดลูกและไม่มีรายการ include_association
หรือ exclude_association
คุณยังคงต้องเปิดใช้งานการคัดลอกเรคคอร์ดลูกอย่างชัดเจนโดยการเรียกวิธีการเปิดใช้งานจากภายในบล็อกอะมีบาในแบบจำลองของคุณ
คุณอาจใช้วิธีการกำหนดค่าร่วมกันภายในบล็อกอะมีบาของแต่ละรุ่น ประเภทการเชื่อมโยงที่ได้รับการยอมรับจะมีลำดับความสำคัญเหนือรายการรวมหรือแยกออก สไตล์แบบรวมจะมีความสำคัญมากกว่าสไตล์พิเศษ และสไตล์ที่ชัดเจนทั้งสองนี้จะมีลำดับความสำคัญมากกว่าสไตล์ที่ไม่เลือกปฏิบัติ กล่าวอีกนัยหนึ่ง หากคุณแสดงรายการฟิลด์ที่จะคัดลอก อะมีบาจะคัดลอกเฉพาะฟิลด์ที่คุณแสดงรายการ หรือคัดลอกเฉพาะฟิลด์ที่คุณไม่ได้แยกออก แล้วแต่กรณี นอกจากนี้ หากไม่รู้จักประเภทฟิลด์ ระบบจะไม่คัดลอก ไม่ว่าจะปรากฏในรายการรวมหรือไม่ก็ตาม หากคุณต้องการให้อะมีบาคัดลอกบันทึกย่อยทั้งหมดของคุณโดยอัตโนมัติ อย่าแสดงรายการฟิลด์ใดๆ โดยใช้ include_association
หรือ exclude_association
ไวยากรณ์ตัวอย่างต่อไปนี้ถูกต้องสมบูรณ์ และจะส่งผลให้มีการใช้งานสไตล์ที่ครอบคลุม ลำดับที่คุณเรียกใช้วิธีการกำหนดค่าภายในบล็อกอะมีบาไม่สำคัญ:
หัวข้อคลาส < ActiveRecord::Base has_many :postsendclass โพสต์ < ActiveRecord::Base อยู่ใน:topic has_many:ความคิดเห็น has_many:แท็ก has_many :ผู้เขียน อะมีบา doexclude_association :authorsinclude_association :tagsnullify :date_publishedprepend :title => "สำเนาของ "ผนวก :contents => " (เวอร์ชันที่คัดลอก)"regex :contents => {:replace => /dog/, :with => 'cat'}include_association :authorsenablenullify :topic_id ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน:postend
ตัวอย่างนี้จะคัดลอกแท็กและผู้เขียนโพสต์ทั้งหมด แต่จะคัดลอกความคิดเห็นไม่ได้ นอกจากนี้ยังจะทำให้วันที่เผยแพร่เป็นโมฆะและแยกโพสต์ออกจากหัวข้อเดิม นอกจากนี้ยังจะประมวลผลฟิลด์ของโพสต์ล่วงหน้าเช่นเดียวกับในตัวอย่างการประมวลผลล่วงหน้าก่อนหน้านี้
โปรดทราบว่าเนื่องจากลำดับความสำคัญ จึงมีการใช้สไตล์แบบรวม และรายการช่องที่ยกเว้นจะไม่ได้รับการพิจารณา นอกจากนี้ วิธี enable
ยังซ้ำซ้อนเนื่องจากอะมีบาถูกเปิดใช้งานโดยอัตโนมัติเมื่อใช้ include_association
คำสั่งการประมวลผลล่วงหน้าจะทำงานหลังจากคัดลอกบันทึกย่อยและรันตามลำดับนี้
เขตข้อมูลว่าง
เติมหน้า
ต่อท้าย
ค้นหาและแทนที่
คำสั่งการประมวลผลล่วงหน้าไม่ส่งผลกระทบต่อรายการรวมและรายการแยก
คุณอาจทำให้อะมีบาคัดลอกลูกโซ่ไปเรื่อยๆ เท่าที่คุณต้องการ เพียงเพิ่มบล็อกอะมีบาลงในแต่ละโมเดลที่คุณต้องการให้คัดลอกลูกโซ่ อะมีบาจะเรียกลูกหลานที่เปิดใช้งานโดยอัตโนมัติและคัดลอกด้วยเช่นกัน
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น อะมีบาสามารถทำได้ ความคิดเห็น endendclass < ActiveRecord::Base เป็นของ_to :post has_many: การให้คะแนน อะมีบาสามารถทำได้ คะแนน endendclass < ActiveRecord::Base เป็นส่วนหนึ่งของ: ความคิดเห็นสิ้นสุด
ในตัวอย่างนี้ เมื่อคัดลอกโพสต์ อะมีบาจะคัดลอกความคิดเห็นของโพสต์ทั้งหมด และจะคัดลอกการให้คะแนนของความคิดเห็นแต่ละรายการด้วย
การใช้ has_one :through
การเชื่อมโยงนั้นง่ายดาย เพียงแค่ต้องแน่ใจว่าได้เปิดใช้งานอะมีบากับแต่ละโมเดลด้วยการเชื่อมโยง has_one
แล้วอะมีบาจะเจาะลึกโดยอัตโนมัติและแบบวนซ้ำ เช่น:
ซัพพลายเออร์คลาส < ActiveRecord::Base has_one :บัญชี has_one :history, :through => :account อะมีบาสามารถทำได้ บัญชี endendclass < ActiveRecord::Base เป็นของ:ซัพพลายเออร์ has_one:ประวัติศาสตร์ อะมีบาสามารถทำได้ ประวัติ endendclass < ActiveRecord::Base อยู่ใน:บัญชี
การคัดลอก has_many :through
การเชื่อมโยงจะทำงานโดยอัตโนมัติ โดยดำเนินการคัดลอกในลักษณะเดียวกับการเชื่อมโยง has_and_belongs_to_many
ซึ่งหมายความว่าเรคคอร์ดย่อยตามจริงจะไม่ถูกคัดลอก แต่การเชื่อมโยงจะคงอยู่อย่างเรียบง่าย คุณสามารถเพิ่มตัวประมวลผลล่วงหน้าบางฟิลด์ลงในโมเดลกลางได้หากต้องการ แต่ไม่จำเป็นอย่างยิ่ง:
แอสเซมบลีคลาส < ActiveRecord::Base has_many: รายการ has_many :parts, :through => :manifests อะมีบาสามารถทำได้ endendclass Manifest < ActiveRecord::Base อยู่ใน:assembly เป็นของ_to:ส่วนหนึ่ง อะมีบา doprepend :notes => "สำเนาของ " ส่วน endendclass < ActiveRecord::Base has_many: รายการ has_many :assemblies, :through => :manifests อะมีบาสามารถทำได้ สิ้นสุด
คุณสามารถควบคุมวิธีที่อะมีบาคัดลอกวัตถุของคุณได้ทันทีโดยส่งบล็อกการกำหนดค่าไปยังวิธีอะมีบาของแบบจำลอง วิธีการกำหนดค่าเป็นแบบคงที่ แต่จะใช้การกำหนดค่าตามอินสแตนซ์
คลาสโพสต์ < ActiveRecord::Base has_many:ความคิดเห็น อะมีบา doenableprepend :title => "สำเนาของ " ความคิดเห็น endendclass < ActiveRecord::Base อยู่ใน: postendclass PostController < ActionController defซ้ำซ้อน_a_postold_post = Post.create( :title => "Hello world", :contents => "Lorum ipsum")old_post.class.amoeba ทำเติมหน้า :contents => "นี่คือสำเนา: "endnew_post = old_post.amoeba_dupnew_post.title # ควรเป็น "สำเนาของ Hello world"new_post.contents # ควรเป็น "นี่คือสำเนา: Lorum อิปซัม"new_post.save สิ้นสุด
หากคุณใช้ Single Table Inheritance ที่ได้รับจาก ActiveRecord คุณอาจทำให้อะมีบาประมวลผลคลาสย่อยโดยอัตโนมัติในลักษณะเดียวกับผู้ปกครอง สิ่งที่คุณต้องทำคือเรียกวิธี propagate
ภายในบล็อกอะมีบาของคลาสพาเรนต์ และคลาสย่อยทั้งหมดควรคัดลอกในลักษณะเดียวกัน
create_table :products, :force => true ทำ |t| t.string :type # นี่คือคอลัมน์ STI #สินค้าเหล่านี้เป็นสินค้าทั้งหมด t.string :title t.ทศนิยม :price #เฉพาะเสื้อเชิ้ตเท่านั้น t.ทศนิยม :sleeve_length t.ทศนิยม :collar_size # มีไว้สำหรับคอมพิวเตอร์เท่านั้น t.จำนวนเต็ม :ram_size t.integer :hard_drive_sizeendclass สินค้า < ActiveRecord::Base has_many :รูปภาพ has_and_belongs_to_many:หมวดหมู่ อะมีบาสามารถแพร่กระจายได้ เสื้อ endendclass < Productendclass Computer < Productendclass ProductsController def some_methodmy_shirt = Shirt.find(1)my_shirt.amoeba_dupmy_shirt.save# เสื้อตัวนี้ควรตอนนี้:# - มีสำเนารูปภาพพาเรนต์ทั้งหมดของตัวเอง# - อยู่ในหมวดหมู่เดียวกันกับพาเรนต์ สิ้นสุด
ตัวอย่างนี้ควรทำซ้ำรูปภาพและส่วนทั้งหมดที่เกี่ยวข้องกับเสื้อตัวนี้ ซึ่งเป็นรายการย่อยของผลิตภัณฑ์
ตามค่าเริ่มต้น การเผยแพร่จะใช้การเลี้ยงดูแบบยอมจำนน ซึ่งหมายความว่าการตั้งค่าการกำหนดค่าบนพาเรนต์จะถูกนำไปใช้ แต่การตั้งค่าลูกใดๆ ถ้ามี จะเพิ่มหรือเขียนทับการตั้งค่าพาเรนต์ ขึ้นอยู่กับวิธีที่คุณเรียกใช้เมธอด DSL
คุณสามารถเปลี่ยนลักษณะการทำงานนี้ ซึ่งเรียกว่า "รูปแบบการเลี้ยงดู" เพื่อให้การตั้งค่าการตั้งค่าของผู้ปกครองหรือละเว้นการตั้งค่าของบุตรหลานทั้งหมด
รูปแบบการเลี้ยงลูก :relaxed
จะชอบการตั้งค่าของผู้ปกครองมากกว่า
คลาสผลิตภัณฑ์ < ActiveRecord::Base has_many :รูปภาพ has_and_belongs_to_many:ส่วน อะมีบา doexclude_association :imagespropagate :ผ่อนคลาย เสื้อ endendclass < สินค้า รวม_สมาคม :รูปภาพ include_association :ส่วน prepend :title => "สำเนาของ "end
ในตัวอย่างนี้ การตั้งค่า include_association
ที่ขัดแย้งกันบนรายการย่อยจะถูกละเว้น และระบบจะใช้การตั้งค่า exclude_association
ระดับบนสุด