12/08/2018, 16:37

Giới thiệu gem Amoeba

Trong quá trình làm dự án Rails, chắc hẳn các bạn đã nhiều lần cần dupplicate một record nào đó. Rails đã có sẵn một phương thức .dup để giúp các bạn làm điều này, tuy nhiên phương thức này chỉ dupplicate record đó, còn những relation liên quan thì không, vậy nếu các bạn muốn dupplicate luôn những ...

Trong quá trình làm dự án Rails, chắc hẳn các bạn đã nhiều lần cần dupplicate một record nào đó. Rails đã có sẵn một phương thức .dup để giúp các bạn làm điều này, tuy nhiên phương thức này chỉ dupplicate record đó, còn những relation liên quan thì không, vậy nếu các bạn muốn dupplicate luôn những relation liên quan thì phải làm sao? Tất nhiên việc đó là có thể, tuy nhiên sẽ khá là rườm rà, nên hôm nay mình xin giới thiệu về gem Amoeba, một gem sẽ giúp bạn làm điều đó một cách dễ dàng.

Các kiểu association hỗ trợ

Gem amoeba hỗ trợ các kiểu association sau:

  • has_many
  • has_one :through
  • has_many :through
  • has_and_belongs_to_many

Sử dụng

  • Install gem:
gem install amoeba

hoặc thêm dòng sau vào Gemfile

gem 'amoeba'

Tạo hai model có association như sau:

class Post < ActiveRecord::Base
  has_many :comments

  amoeba do
    enable
  end
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Thiết lập model của bạn như trên và sau đó chỉ cần chạy phương thức amoeba_dup trên mô hình của bạn nơi bạn sẽ chạy phương thức dup thông thường:

p = Post.create(title: "Hello World!",  content: "Lorum ipsum dolor")
p.comments.create(content: "I love it!")
p.comments.create(content: "This sucks!")

puts Comment.all.count # should be 2

my_copy = p.amoeba_dup
my_copy.save

puts Comment.all.count # should be 4

Theo mặc định khi enable, child records sẽ tự động copy khi bạn chạy phương thức amoeba_dup. Tuy nhiên, không phải lúc nào chúng ta cũng cần lấy hết các childs record, để lấy các childs record mà chúng ta cần thì amoeba đã cung cấp cho chúng ta phương thức include_association, hoặc exclude_association

class Post < ActiveRecord::Base
  has_many :comments
  has_many :tags
  has_many :authors

  amoeba do
    include_association :tags
    include_association :authors
  end
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Theo ví dụ trên, khi chúng ta dùng amoeba_dup thì chỉ có tags và authors sẽ được tự động khởi tạo, còn comments sẽ không được tạo nữa.

class Post < ActiveRecord::Base
  has_many :comments
  has_many :tags
  has_many :authors

  amoeba do
    exclude_association :comments
  end
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Ở đây chúng ta dùng exclude_association thì khi dùng amoeba_dup thì tất cả các childs record khác sẽ tự động tạo, ngoại trừ comments

Chúng ta cũng có thể thêm điều kiện khi nào amoeba_dup sẽ tự động tạo childs record.

class Post < ActiveRecord::Base
  has_many :comments
  has_many :tags

  amoeba do
    include_association :comments, if: :popular?
  end
  
  def popular?
    likes > 15
  end
end

Nếu like > 15 thì comments sẽ được copy, ngược lại thì không. Tương tự cho exclude_association.

Trên đây mình đã giới thiệu sơ qua về gem Amoeba, giúp các bạn dễ dàng hơn trong việc dupplicate record và các association liên quan của nó. Gem amoeba còn có nhiều thứ hay ho nữa, các bạn có thể tìm hiểu thêm ở đây Cảm ơn các bạn đã đọc bài.

0