Gem virtus và cách dùng trong ứng dụng Rails
Virtus hoạt động theo một cách gần như giống Property trong DataMapper. Virtus works in an almost identical way as Property in DataMapper. You can define attributes in your classes and it will create accessors to these attributes along with typecasting abilities. It comes with a set of builtin ...
Virtus hoạt động theo một cách gần như giống Property trong DataMapper.
Virtus works in an almost identical way as Property in DataMapper. You can define attributes in your classes and it will create accessors to these attributes along with typecasting abilities. It comes with a set of builtin attribute types but you are free to add your own types too
Virtus cho phép tạo các thuộc tính của class, module hay các instance class với các thông tin tùy chọn về type khả năng hiển thị method đọc / ghi và các hành vi ép buộc(coercion behavior). Ngoài ra, nó cũng hỗ trợ rất nhiều coercion và mapping nâng cao của các đối tượng nhúng và collection.
Một số trường hợp nên dùng virtus:
- Nhập các pamatters sanitization và ép buộc trong các ứng dụng web
- mapping JSON tới các domain object
- Đóng gói data-access trong các Value Object
- Tạo các domain model
Cài đặt
Có 2 cách cài đặt như các gem thông thường khác bạn có thể thực hiện như sau:
- Cách 1: Cho trực tiếp vào file Gemfile:
//Gemfile gem "virtus"
và sau đó chạy lệnh bundle install trên terminal.
- Cách 2: Chạy trực tiếp lệnh gem install virtus trên terminal
Cách dùng
Available Attribute Types:
Dưới đây là các type attributes mà có thể khởi tạo kiểu khi dùng virtus:
- Array
- Boolean
- Date
- DateTime
- Decimal
- Float
- Hash
- Integer
- Object
- String
- Time
1. Dùng virtus với classes:
Chúng ta có thể tạo class kế thừa từ Virtus và tạo các attributes như sau:
class Book include Virtus attribute :title, String attribute :author, String attribute :publish_date, Date book = Book.new(:title => "Tôi Và Paris - Câu Chuyện Một Dòng Sông", :author => "Hoàng Long") book.attributes # => { :title => "Tôi Và Paris - Câu Chuyện Một Dòng Sông", :author => "Hoàng Long", :publish_date => nil } book.title # => "Tôi Và Paris - Câu Chuyện Một Dòng Sông" book.author # => "Hoàng Long" end
2. Dùng virtus với module:
Chúng ta có thể tạo modules kế thừa từ Virtus và tạo các attributes sau đó include vào các class muốn sử dụng:
module Title include Virtus.module attribute :title, String end module Author include Virtus.module(:coerce => false) attribute :author, String end class Book include Title, Author end book = Book.new(:title => "Tôi Và Paris - Câu Chuyện Một Dòng Sông", :author => "Hoang Long")
3. Tạo một Dynamically Extending Instances
class Book # nothing here end book = Book.new book.extend(Virtus.model) book.attribute :title, String book.title = "Tôi và Paris - câu chuyện một dòng sông" book.title # => "Tôi và Paris - câu chuyện một dòng sông"
4. Các giá trị mặc định(Default Values)
class Page include Virtus.model attribute :title, String # default from a singleton value (integer in this case) attribute :views, Integer, :default => 0 # default from a singleton value (boolean in this case) attribute :published, Boolean, :default => false # default from a callable object (proc in this case) attribute :slug, String, :default => lambda { |page, attribute| page.title.downcase.gsub(' ', '-') } # default from a method name as symbol attribute :editor_title, String, :default => :default_editor_title def default_editor_title published? ? title : "UNPUBLISHED: #{title}" end end page = Page.new(:title => 'Virtus README') page.slug # => 'virtus-readme' page.views # => 0 page.published # => false page.editor_title # => "UNPUBLISHED: Virtus README" page.views = 10 page.views # => 10 page.reset_attribute(:views) # => 0 page.views # => 0
5. Giá trị defaul trên các dynamically extended instance
Cái này yêu cầu cần sử dụng thêm option :lazy (setting mặc định là false)
book = Book.new book.extend(Virtus.model) book.attribute :title, String, default: 'Tôi và Paris - câu chuyện một dòng sông', lazy: true book.name # => "jane"
6. Embedded Value
- Cùng xem ví dụ sau:
class City include Virtus.model attribute :name, String end class Address include Virtus.model attribute :street, String attribute :zipcode, String attribute :city, City end class User include Virtus.model attribute :name, String attribute :address, Address end user = User.new(:address => { :street => 'Street 1/2', :zipcode => '12345', :city => { :name => 'NYC' } }) user.address.street # => "Street 1/2" user.address.city.name # => "NYC"
Ở trên đây là những điều cơ bản nhất về gem virtus
Tham khảo từ Virtus – Attributes For Your Plain Ruby Objects và gem virtus