vinber 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5846099a1282c804d8caee37689c761e2c46e8f4
4
- data.tar.gz: b06ec6b47bb81c6e8349064513aae54b9e8ef2aa
3
+ metadata.gz: 0e998cd2a9472e745967acb3344182b7a1af4df1
4
+ data.tar.gz: e208761a1a37fa1a0ec676b565b249c2ae112bfb
5
5
  SHA512:
6
- metadata.gz: 40dca19b242327e0c29915d62a528a1983f5b632d7ae6667d359809045402eb30f80351ac2549608fd6d8b69bbe7eb0e36c1a0a72abeb1c4ef7d81a05d6ab0de
7
- data.tar.gz: 4a73b9e8f2b025307a0a351817a6c9206b0757eb1872218270e618b71b0d21cee1af459f00f59767795e4270c0a50c7f499fe1d5f534b88b3497484529a19ac8
6
+ metadata.gz: 25c68c7efa5884c70c3e0b0350162cda2b7ffdd4e5dfb3a23f44565cec4c24b0b3cfeef74d65a95e39acde14948649faeabd23abba2803a56c5bbb1a058ab3bd
7
+ data.tar.gz: de6429a9e832dde6d1aa4386dd63643cdc5dfd40c7bdb111bef7c0a7011397c2508f6edc19bd980c71093bc636351f41e8db7b30770f0b22cfca71e206366e07
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ # Default
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /Gemfile.lock
@@ -10,3 +11,39 @@
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
14
+
15
+ ## MAC OS
16
+ .DS_Store
17
+
18
+ ## TEXTMATE
19
+ *.tmproj
20
+ tmtags
21
+
22
+ ## EMACS
23
+ *~
24
+ \#*
25
+ .\#*
26
+
27
+ ## VIM
28
+ *.swp
29
+
30
+ ## RUBYMINE
31
+ .idea
32
+
33
+ ## PROJECT::GENERAL
34
+ coverage
35
+ rdoc
36
+ pkg
37
+ .ruby-version
38
+ gemfiles/*.gemfile.lock
39
+ Gemfile.lock
40
+ /tmp
41
+ /.bundle
42
+ /gemfiles/.bundle
43
+
44
+ ## PROJECT::RVM
45
+ .rvmrc
46
+
47
+ # PROJECT::RBENV
48
+ .ruby-gemset
49
+ *.gem
data/README.md CHANGED
@@ -1,90 +1,120 @@
1
1
  ## Vinber ##
2
2
 
3
- Vinber works for Rails, provides other way enumeration style which without force format output and force method definations.
3
+ Enumeration with I18N solution for Rails, which without force output formatting and force method defining.
4
4
 
5
- __NOTE__: Vinber current version *require* Ruby v1.9.0 or later and just tested on Rails 4.x for now .
5
+ __NOTE__: vinber works fine with Rails 4.x or later.
6
6
 
7
7
 
8
8
  ### Installation ###
9
- # Installing as Ruby gem
9
+ # Manually from RubyGems.org
10
10
  $ gem install vinber
11
11
 
12
- # Or in gemfile
12
+ # Or Gemfile if you are using Bundler
13
13
  $ gem vinber
14
14
 
15
15
  ### Usage ###
16
+ To use vinber is as simple as defining table attribute in its Model, and using Hash or Array are supported:
16
17
 
17
- #### vinber
18
- You will be able to use `vinber` in any model which inherit `ActiveRecord::Base`.
19
18
  ```ruby
20
- vinber attribute: {} # hash
21
- vinber attribute: [] # array
22
- ```
19
+ # app/models/user.rb
20
+ # User(id: integer, name: string, :status: integer, language: string)
21
+ class User < ActiveRecord::Base
23
22
 
24
- ### vinber_list
25
- `vinber_list` return a nested Array, it besides the attribute I18n value and vinber key.
26
- ```ruby
27
- vinber_list class_object, attribute
23
+ vinber :status => {:registered => 1, :active => 2, :locked => 3}
24
+
25
+ end
28
26
  ```
29
27
 
30
- ### vinber_value
31
- `vinber_value` return the I18n value of specific attribute.
28
+ This provides you with a couple of public methods for class `User` and its instances:
32
29
 
33
30
  ```ruby
34
- vinber_value instance_object, attribute
31
+ User.defined_vinbers # => {'status' => {:registered => 1, :active => 2, :locked => 3}}
32
+ User.vinber_defined? # => true
33
+ User.vinber_defined?(:status) # => true
34
+ User.vinber_defined?(:language) # => false
35
+ User.vinbers.status # => {:registered => 1, :active => 2, :locked => 3}
36
+ User.vinber_list(:status) # => [['Registered', 1], ['Active', 2], ['Locked', 3]]
37
+
38
+ # We assume there are a lot of records in User Table
39
+ User.first.status # => 2
40
+ User.first.vinber_value(:status) # => 'Active'
41
+
42
+ # if the attribute not defined by vinber, vinber_value return the real value
43
+ User.vinber_defined?(:id) # => false
44
+ User.first.vinber_value(:id) # => 1
35
45
  ```
36
46
 
37
- ### Examples ###
38
- Step 1, you need define your vinbers in your model.
47
+ ### i18n ###
48
+ You will be able to use i18n of vinber when you defines attribute with `Hash`, as default, vinber always try to find the translation from current local yaml file. if not found, vinber will fetch the attribute and return the right hash key string.
39
49
 
40
50
  ```ruby
41
- # app/models/your_models.rb
42
- class YourModel < ActiveRecord::Base
43
- ...
44
-
45
- vinber :status => {:submited => 1, :processing => 2, :completed => 3}
46
-
47
- ...
48
- end
51
+ User.first.status # => 2
52
+ User.first.vinber_value(:status) # => 'Active'
53
+ User.vinber_list(:status) # => [['Registered', 1], ['Active', 2], ['Locked', 3]]
49
54
  ```
55
+ Setting locale like below format:
50
56
 
51
- Step 2, set your locale for I18n.
52
57
  ```yaml
53
58
  # config/locales/zh.yml or en.yml(any yml your want)
54
59
  zh:
55
60
  vinber:
56
- YourModel:
57
- status_submited: 提交
58
- status_processing: 进行中
59
- status_completed: 完成
61
+ User:
62
+ status_registered: 已注册
63
+ status_active: 已激活
64
+ status_locked: 锁定中
60
65
 
61
66
  ```
62
67
 
63
- Step 3, invoking in view !! We assume you has YourModel and it contains records, the status of first record is `2`.
68
+ If current locale is `zh`, you will see:
64
69
 
65
- ```haml
66
- # app/views/your_modles/index.haml
67
- - obj = YourModel.first
68
- %p= vinber_value(obj, :status)
70
+ ```ruby
71
+ User.first.vinber_value(:status) # => '已激活'
72
+ User.vinber_list(:status) # => [['已注册', 1], ['已激活', 2], ['锁定中', 3]]
73
+ ```
74
+
75
+ Alternative, if you don't want it to be translated, just use `:t => false`, this will be useful when you writing api program, you don't want different locals to change the result.
76
+
77
+ ```ruby
78
+ User.first.vinber_value(:status, :t => false) # => 'active'
79
+ User.vinber_list(:status, :t => false) # => [['registered', 1], ['active', 2], ['locked', 3]]
80
+ ```
69
81
 
70
- # => <p>进行中</p>
82
+ Sometimes, the array by `vinber_list` is not what you expect, you could use block to customize:
71
83
 
72
- = form_tag({}) do
73
- = select_tag "status", options_for_select(vinber_list YourModel, :status)
84
+ ```ruby
85
+ User.vinber_list(:status) do |key, value|
86
+ "#{key}: #{value}"
87
+ end
88
+ # => ["已注册: 1", "已激活: 2", "锁定中: 3"]
89
+
90
+ User.vinber_list(:status, :t => false) do |key|
91
+ key.upcase
92
+ end
93
+ # => ["REGISTERED", "ACTIVE", "LOCKED"]
94
+ ```
95
+
96
+ ### Validates ###
97
+
98
+ For database safety, vinber provides validates to check security of value when saving, but it's disabled by default, you can enable with option `:validates => true`.
99
+
100
+ ```ruby
101
+ class User < ActiveRecord::Base
102
+
103
+ vinber :status => {:registered => 1, :active => 2, :locked => 3}, :validates => true
104
+
105
+ end
74
106
 
75
- # => <form accept-charset="UTF-8" method="post">
76
- # => <select name="status" id="status">
77
- # => <option value="1">提交</option>
78
- # => <option value="2">进行中</option>
79
- # => <option value="3">完成</option>
80
- # => </select>
81
- # => </form>
107
+ user = User.new(
108
+ :name => 'Charles',
109
+ :status => 4 # status is 4, expected in [1, 2, 3]
110
+ )
111
+ user.save # false
112
+ user.errors.messages # {:status => ["is not included in the list"]}
82
113
  ```
83
114
 
84
115
  ### TODO ###
85
- - Write more clear document
86
- - Add soft warning when error
87
- - more functions
116
+ - Improve compatibility
117
+ - Make it easy to ActiveRecord Query
88
118
 
89
119
  ### License ###
90
120
  Released under the [MIT](http://opensource.org/licenses/MIT) license. See LICENSE file for details.
@@ -0,0 +1,19 @@
1
+ module Vinber
2
+ class CurrentVinbers
3
+
4
+ attr :vinbers
5
+
6
+ def initialize(vinbers = {})
7
+ @vinbers = vinbers.with_indifferent_access
8
+ end
9
+
10
+ def method_missing(name, *args)
11
+ if vinbers.has_key? name
12
+ vinbers[name]
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module Vinber
2
+ class Translate
3
+
4
+ VALUE_LABLE = "vinber.%{klass}.%{attribute}_%{key}"
5
+
6
+ def initialize(klass, attribute, attribute_vinber_key)
7
+ @label = {
8
+ :klass => (klass.is_a?(Class) ? klass.name : klass),
9
+ :attribute => attribute,
10
+ :key => attribute_vinber_key
11
+ }
12
+ end
13
+
14
+ def label
15
+ @label ||= %()
16
+ end
17
+
18
+ def text
19
+ @text ||= I18n.t (VALUE_LABLE % label), default: label[:key].to_s.humanize
20
+ end
21
+
22
+ alias_method :to_s, :text
23
+
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Vinber
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,21 @@
1
+ module Vinber
2
+ module List
3
+
4
+ def vinber_list(attribute, options = {}, &block)
5
+ klass = self
6
+ raise VinberUndefined, "Vinber was undefined in #{klass.name}" unless klass.vinber_defined?
7
+
8
+ need_tanslate = options.fetch(:t){true}
9
+ if klass.vinber_defined? attribute
10
+ attribute_vinber = klass.defined_vinbers[attribute.to_s]
11
+ return attribute_vinber unless attribute_vinber.is_a?(Hash)
12
+
13
+ attribute_vinber.map do |key, value|
14
+ key = Vinber::Translate.new(klass, attribute, key).to_s if need_tanslate
15
+ block_given?? block.call(key, value) : [key, value]
16
+ end
17
+ end.to_a
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Vinber
2
+ module Value
3
+
4
+ def vinber_value(attribute, options = {})
5
+ obj = self
6
+ klass = obj.class
7
+ val = obj.send(attribute.to_sym)
8
+ api = options.fetch(:t) {false}
9
+
10
+ if klass.vinber_defined?(attribute) &&
11
+ (attribute_vinber = klass.defined_vinbers[attribute.to_s]).is_a?(Hash)
12
+
13
+ attribute_vinber_key = attribute_vinber.key val
14
+ api ? attribute_vinber_key.to_s : Vinber::Translate.new(klass, attribute, attribute_vinber_key).to_s
15
+ else
16
+ val
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+
data/lib/vinber.rb CHANGED
@@ -18,7 +18,10 @@ module Vinber
18
18
  end
19
19
 
20
20
  def vinber(definitions)
21
+ need_validates = definitions.delete(:validates)
21
22
  definitions.each do |name, values|
23
+ detect_vinber_conflict! name
24
+ validates_from_vinber name, values if need_validates
22
25
  defined_vinbers[name.to_s] = case
23
26
  when values.is_a?(Hash)
24
27
  values.with_indifferent_access
@@ -37,16 +40,38 @@ module Vinber
37
40
  def vinber_defined?(attr_key = nil)
38
41
  attr_key ? defined_vinbers.has_key?(attr_key.to_s) : defined_vinbers.present?
39
42
  end
40
- end
41
43
 
42
- # Extend/Include to Rails
43
- ActiveRecord::Base.extend Vinber
44
- ActiveRecord::Base.extend Vinber::Value
45
- ActiveRecord::Base.send(:include, Vinber::Value)
44
+ private
45
+
46
+ VINBER_CONFLICT_MESSAGE = \
47
+ "You tried to define a vinber named %{name} in %{klass}, but it's already defined by %{source}."
48
+
49
+ def detect_vinber_conflict!(name)
50
+ if vinber_defined?(name)
51
+ raise_vinber_conflict_error(name, 'Vinber')
52
+ elsif defined_enums[name.to_s]
53
+ raise_vinber_conflict_error(name, 'Enum')
54
+ end
55
+ end
46
56
 
47
- ApplicationHelper.extend Vinber::Value
48
- ApplicationHelper.send(:include, Vinber::Value)
49
- ApplicationHelper.send(:include, Vinber::List)
57
+ def validates_from_vinber(name, val)
58
+ val = val.is_a?(Hash) ? val.values : Array.wrap(val).flatten
59
+ class_eval { validates name.to_sym, inclusion: {in: val} }
60
+ end
50
61
 
51
- ApplicationController.extend Vinber::Value
52
- ApplicationController.send(:include, Vinber::Value)
62
+ def raise_vinber_conflict_error(name, source)
63
+ raise ArgumentError, VINBER_CONFLICT_MESSAGE % {
64
+ name: name,
65
+ klass: self.name,
66
+ source: source
67
+ }
68
+ end
69
+
70
+ end
71
+
72
+ # Extend/Include to ActiveRecord::Base
73
+ ActiveRecord::Base.class_eval do
74
+ extend Vinber
75
+ extend Vinber::List
76
+ include Vinber::Value
77
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vinber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cenxky
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-30 00:00:00.000000000 Z
11
+ date: 2017-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -55,7 +55,11 @@ files:
55
55
  - bin/console
56
56
  - bin/setup
57
57
  - lib/vinber.rb
58
+ - lib/vinber/current_vinbers.rb
59
+ - lib/vinber/translate.rb
58
60
  - lib/vinber/version.rb
61
+ - lib/vinber/vinber_list.rb
62
+ - lib/vinber/vinber_value.rb
59
63
  - vinber.gemspec
60
64
  homepage: https://github.com/cenxky/vinber
61
65
  licenses: