Project

model_pack

0.0
No commit activity in last 3 years
No release in over 3 years
Using Ruby classes aka ("models") with smart serialization mechanizm
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.12
~> 10.0
~> 3.0
 Project Readme

Model Pack - model interfaces

Model Pack - набор интерфейсов, который позволяет создавать специальные атрибуты в объекте. Также добавляет методы работы model attributes. Позволяет сериализовывать атрибуты модели, сохраняя их правильную иерархию.

Model Pack is an interfaces collection for creating object's attributes. It also adds methods for working with this attributes and allows to safely serialize your model without loosing their hierarchical structure.

Installation

Add this line to your application's Gemfile:

gem 'model_pack'

And then execute:

$ bundle

Or install it yourself as:

$ gem install model_pack

Использование

Атрибуты и вложенные объекты

class Point
  include ModelPack::Document

  attribute :x
  attribute :y
end

class Line
  include ModelPack::Document

  object :from, class_name: Point
  object :to, class_name: Point

  def length
     Math.sqrt((from.x-to.x)**2 + (from.y-to.y)**2)
  end
end

Создаем экземпляры модели:

point = Point.new(x: 3, y: 5)
line = Line.new(
	from: { x: 1, y: 1 },
	to: { x: 3, y: 5}
)
puts line.length

Перекрываем запись атрибутов

class Text
  attribute :always_string, writer: ->(v) { v.to_s }
end

text = Text.new(always_string: 123)
puts text.always_string # "123"

Массив моделей

class Polygon
	include ModelPack::Document

	array :points, class_name: Point

	def sides
		return [] if points.size < 2
		[[points.first]].tap do |sides|
			(1...(points.size)).to_a.each do |index|
				sides.last.push points[index]
				sides.push [points[index]]
      			end
      			sides.last.push(points.first)
    		end
 	end

	def perimeter
		sides.inject(0) { |sum, side| sum + Math.sqrt((side[0].x-side[1].x)**2 + (side[0].y-side[1].y)**2) }
	end
end
polygon = Polygon.new(points: [{x: 0, y: 0}, {x:5, y:0}, {x:5, y:5}])
puts polygon.perimeter

Сериализация моделей

polygon = Polygon.new(points: [{x: 0, y: 0}, {x:5, y:0}, {x:5, y:5}])
json = polygon.as_json     # same serializable_hash

Копирование моделей

polygon = Polygon.new(points: [{x: 3, y: 3}, {x:2, y:1}, {x:4, y:2}])
polygon_copy = polygon.copy   # same polygon_copy = Polygon.new(polygon.serializable_hash)
puts polygon_copy.serializable_hash

Выборочная сериализация

class SecureData
	include ModelPack::Document
	attribute :hidden_field, serialize: lambda { |v| nil }
	attribute :const_field, serialize: lambda { |v| :always_this }
	attribute :always_string, serialize: lambda { |v| v.to_s }
end
secure_data = SecureData.new( hidden_field: "secured text", const_field: :some_value, always_string: 55)
unsecure_hash = secure_data.serializable_hash
puts unsecure_hash

Наследование

Для того чтобы использовать всю мощь ModelPack, но при этом не переопределять конструктор через ModelPack::Constructor существует класс ModelPack::Super, от которого можно наследоваться. Однако в этом случае необходимо явно передавать в super аргументы, которые вы хотите установить в модель

class MyClass < ModelPack::Super
  attribute :foo
  attribute :bar, default: "default value"
  
  def initialize(args)
    # do some work with args, may be collect from it foo and bar values
    my_foo_bar_values = some_work_with_args(args)
    super(my_foo_bar_values)
  end
end

Также можно расширять список атрибутов от родителя к наследнику

class Child < MyClass
  attribute :baz # attributes `foo` and `baz` are also available
end

Contributing

  1. Fork it ( https://github.com/inre/model_pack/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request