can_camel 0.2.1 → 0.3.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: 6cd2a7e24ff8c42df996b7255ecfc0710ae5b011
4
- data.tar.gz: 97d7813911fdbbcc34c765243df8f047fceef026
3
+ metadata.gz: b7327da083e2094e5ec46012cd8d677fa1d580a3
4
+ data.tar.gz: de42690b702c3cf0be312f3a284efdd7d2a8b9da
5
5
  SHA512:
6
- metadata.gz: 89e48cc509dfe2269a5f308e3234fbcbe2400642b22c916b44937b72f32fcbfb57eaa28de6d4162b23e4d69f37cd4a6a222ca79270994faf6a29d0ff01ba5338
7
- data.tar.gz: c765a6da93ea8aa404105b405a22a8598348a5c4a42b54c36655f6c471c61d46228eeb3c077962f88c933457aa4a641ec09e641dc4d3fd3d4faf16e1b86e18e2
6
+ metadata.gz: d990335cb5d604df985bb522370aabe0ac0750e516a51570c9d1485309bfec14acad9d254cc450e02f570766b01311db060fe682da20a353f3fd53a41fbda428
7
+ data.tar.gz: d43fd37f23f2cdcfcf28e63281b312ab7d9e714e79412a78a3d90547261e256c5886fc08a5c5e648719d753f8f8d94beae5bc02fad7c56e2207291b8ad878cf4
data/README.md CHANGED
@@ -14,18 +14,16 @@ can be passed to a filter. Any custom filters could be made and any additional d
14
14
 
15
15
  Step 1. Installation
16
16
  ====================
17
- run rails g can_camel:install <br>
17
+ run `rails g can_camel:install` <br>
18
18
  Then visit generated initializer at config/initializers/can_camel.rb
19
19
  <pre>
20
- # CanCamel::Filters.include AbilityFilters
21
20
  CanCamel::TABLE_NAME = "can_camel_nodes"
22
21
  CanCamel::GROUP_METHOD = :group
23
22
  </pre>
24
- First line describes how to use you own filters. You may prefer `prepend` over `include`
25
- here. You can also specify table name, if you want. Third line describes a symbol, which references for
23
+ In first line you can specify table name or use default. Second line describes a symbol, which references for
26
24
  user model method, returning user group. Group should be a symbol. Visit spec/dummy/app/models/user.rb
27
- for example. When you sure with this file, run generated migration.
28
- Remember, that migration installs 'hstore' plugin, on which relies,
25
+ for example. When you sure with this file, run generated migrations.
26
+ Remember, that migrations installs 'hstore' plugin, on which relies,
29
27
  but does not remove it. If you want to revert it, you may want to remove plugin too
30
28
 
31
29
  Step 2. Database structure
@@ -34,29 +32,39 @@ Database consists of nodes. Primary nodes (WHERE parent_id IS NULL) are called s
34
32
  Their children are called actions, and actions' children are called groups. Groups' children
35
33
  are called garbage and never used. Any node can have conditions and results. Conditions' syntax is
36
34
  <pre>
37
- [
38
- { method: :day_of_week, allow: %w(saturday sunday) }
39
- ]
35
+ { at_day: { wdays: [6] } }
40
36
  </pre>
41
- It means, that :day_of_week will be called with `allow: {"saturday", "sunday}"` argument
37
+ It means, that :at_day will be called with `wdays: [6]` argument
42
38
 
43
39
  Step 3. Linting
44
40
  ===============
41
+ _I suggest to call `CanCamel.lint` each time you modifying can_camel objects because it is beta_ <br>
45
42
  If you are working primary with database (e.g. in migration), you can call
46
43
  `CanCamel.lint` to check is database correct. Best way is to call `CanCamel.lint!` in transaction
47
- with all changes done and enjoy your exception if need
44
+ with all changes done and enjoy your exception if need.
48
45
 
49
- Step 4. Constrains (Incomplete)
50
- ===============================
51
- Filters have great powers, and with big power big responsibility comes. For example, you are managing
52
- statistics access on Users, and your filter scoping them. What if your filter would be called for Blog?
53
- I think, nothing good. To prevent it, you can write a constraint
54
- <pre>
55
- validate :filter_name, subject: :user
56
- def filter_name
57
- #TODO: do something
58
- end
59
- </pre>
46
+ Step 4. Custom filters and Constrains
47
+ =====================================
48
+ Filters subsystem relies on a `CanCamel::Filter` module, which automatically inserts
49
+ `register_filter` method when included. This method can take as first argument high variety of things
50
+ 1. If it takes a symbol and lambda, it will define a simple filter without argument filtering
51
+ 2. If it takes a method or symbol referencing a method, it will register that method as in previous api: as a simple
52
+ filter
53
+ 3. If it takes a class respond to `invoke!` and `name` methods, it will register its element
54
+ 4. If it takes something else respond to `invoke` and `name` methods, it will register it as is
55
+
56
+ You can use old style validation or use validate! method in objects passed
57
+
58
+ Old Style Validation
59
+ --------------------
60
+ Include `CanCamel::Validators` to use validates method. You can add custom validators extending
61
+ this class in initializer. Validation syntax is `validates filter [field] validator: params`
62
+
63
+ validate! method
64
+ ----------------
65
+ define `validate!` method for you filters and place your validators here (mostly for semantic)
66
+ you can access improved `validates` method in classes inherited from `CanCamel::Filters::Base`
67
+ this method requires to specify only validators and optionally field name
60
68
 
61
69
  Step 5. Human interface (NIY)
62
70
  ============================
data/lib/can_camel.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module CanCamel
2
2
  extend ActiveSupport::Autoload
3
3
  %i(Base Node SubjectNode ActionNode GroupNode ConcernNode Linter Filters
4
- Validators Cache)
4
+ Validators Cache Filter)
5
5
  .each { |x| autoload(x) }
6
6
 
7
7
  extend CanCamel::Base
@@ -1,8 +1,10 @@
1
1
  module CanCamel
2
2
  class ActionNode < Node
3
3
  has_many :groups, foreign_key: :parent_id, class_name: "CanCamel::GroupNode"
4
- belongs_to :parent, foreign_key: :parent_id, class_name: "CanCamel::SubjectNode"
5
-
6
4
  validates_presence_of :parent_id
5
+
6
+ def rank
7
+ 2
8
+ end
7
9
  end
8
10
  end
@@ -3,8 +3,14 @@ module CanCamel
3
3
  # don't delegate all, because lint_node designed to be run on same instances of linter
4
4
  delegate :lint, :lint!, to: :new_linter
5
5
 
6
+ # returns hash with some return params or nil.
7
+ # @param user [User] user respond to GROUP_METHOD
8
+ # @param action [Symbol] symbol relied to action node name
9
+ # @param subject [Symbol] symbol relied to subject node name
10
+ # @return [Hash, nil] hash with specific params or nil
6
11
  def can?(user, action, subject, **args)
7
- Cache[[user.send(GROUP_METHOD), action, subject]].try(:can?, args)
12
+ Cache[[user.send(GROUP_METHOD).to_sym, action, subject]]
13
+ .try(:can?, user: user, **args)
8
14
  end
9
15
 
10
16
  private
@@ -5,27 +5,45 @@ module CanCamel
5
5
 
6
6
  def reload!
7
7
  @cache = build_cache
8
+ inherit_all!
9
+ end
10
+
11
+ def children_of(node)
12
+ cache.select do |path, _value|
13
+ _, *subpath = path
14
+ node.path == subpath
15
+ end.values
16
+ end
17
+
18
+ def append(node, path)
19
+ path = [node.name, *path]
20
+ @cache[path] = node
21
+ children_of(node).each { |child| append child, path }
8
22
  end
9
23
 
10
24
  private
11
25
 
26
+ # def subpath?(path, subpath)
27
+ # return if path.empty?
28
+ # return true if subpath.empty?
29
+ # return unless path[-1] == subpath[-1]
30
+ # subpath?(path[0...-1], subpath[0...-1])
31
+ # end
32
+
12
33
  def cache
13
- @cache ||= build_cache
34
+ @cache || (reload!; @cache)
14
35
  end
15
36
 
16
37
  def build_cache
17
- SubjectNode.all.each_with_object({}) do |subject_node, object|
18
- subject_name = subject_node.name
19
- subject_node.actions.each do |action_node|
20
- action_name = action_node.name
21
- action_node.groups.each do |group_node|
22
- group_name = group_node.name
23
- group_node.inherit!
24
- object[[group_name, action_name, subject_name]] = group_node
25
- end
26
- end
38
+ Node.all.each_with_object({}) do |node, object|
39
+ object[node.path] = node
27
40
  end
28
41
  end
42
+
43
+ def inherit_all!
44
+ local_cache = cache.dup
45
+ local_cache.each { |_path, node| node.inherit! }
46
+ end
29
47
  end
30
48
  end
31
49
  end
@@ -2,4 +2,8 @@ module CanCamel
2
2
  class ConcernNode < Node
3
3
  validates :parent_id, absence: true
4
4
  end
5
+
6
+ def rank
7
+ 0
8
+ end
5
9
  end
@@ -0,0 +1,40 @@
1
+ module CanCamel
2
+ module Filter
3
+ def self.included(base)
4
+ base.define_singleton_method(:register_filter) { |*args| CanCamel::Filter.register_filter(*args) }
5
+ end
6
+
7
+ class <<self
8
+ def register_filter(x, lambda = nil)
9
+ case x
10
+ when Class
11
+ filter = x.new
12
+ when Symbol
13
+ begin
14
+ filter = Filters::CustomFilter.new(x, lambda || method(x))
15
+ rescue NameError
16
+ raise ArgumentError, "no method #{x} defined and lambda not passed"
17
+ end
18
+ when Method
19
+ filter = Filters::CustomFilter.new(x.name, x)
20
+ else
21
+ filter = x
22
+ end
23
+
24
+ raise ArgumentError, "#{x} is neither Filter nor Class nor Symbol nor Method" unless filter?(filter)
25
+ filter.try(:validate!)
26
+ filters[filter.name] = filter
27
+ end
28
+
29
+ def filters
30
+ @filters ||= {}
31
+ end
32
+
33
+ private
34
+
35
+ def filter?(x)
36
+ %i(invoke! name).reduce { |a, e| a && x.respond_to?(e) }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,19 +1,12 @@
1
1
  require 'can_camel/validators'
2
2
  module CanCamel::Filters
3
3
  include CanCamel::Validators
4
- ArgSyntaxError = Class.new(StandardError)
4
+ include CanCamel::Filter
5
+ extend ActiveSupport::Autoload
5
6
 
6
- module_function
7
+ ABSTRACT_FILTERS = %i(Base CustomFilter)
8
+ FILTERS = %i(AtTime AtDay)
7
9
 
8
- validates :at_time, :hours, presence: {}
9
- def at_time(hours:, **_)
10
- hours.include?(Time.now.hour) && {}
11
- end
12
-
13
- validates :at_day, presence_of: { fields: [:days, :wdays], any: true }
14
- def at_day(days: nil, wdays: nil, **_)
15
- return if days && !days.include?(Time.now.day)
16
- return if wdays && !wdays.include?(Time.now.wday)
17
- {}
18
- end
10
+ (ABSTRACT_FILTERS + FILTERS).each { |x| autoload x }
11
+ FILTERS.each { |x| register_filter const_get(x) }
19
12
  end
@@ -0,0 +1,20 @@
1
+ module CanCamel::Filters
2
+ class AtDay < Base
3
+ def catch_args
4
+ %i(days wdays)
5
+ end
6
+
7
+ def validate!
8
+ validates presence_of: {
9
+ fields: %i(days wdays),
10
+ any: true,
11
+ }
12
+ end
13
+
14
+ def filter(days: nil, wdays: nil)
15
+ return if days && !days.include?(Time.now.day)
16
+ return if wdays && !wdays.include?(Time.now.wday)
17
+ {}
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module CanCamel::Filters
2
+ class AtTime < AtDay
3
+ def catch_args
4
+ %i(hours days wdays)
5
+ end
6
+
7
+ def validate!
8
+ validates presence_of: {
9
+ fields: %i(hours days wdays),
10
+ any: true,
11
+ }
12
+ end
13
+
14
+ def filter(hours: nil, days: nil, wdays: nil)
15
+ return if hours && !hours.include?(Time.now.hour)
16
+ super days: days, wdays: wdays
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ module CanCamel::Filters
2
+ class Base
3
+ def initialize(*)
4
+ end
5
+
6
+ def name
7
+ self.class.to_s.demodulize.underscore.to_sym
8
+ end
9
+
10
+ def catch_args
11
+ nil
12
+ end
13
+
14
+ def catch_result
15
+ []
16
+ end
17
+
18
+ def filter(**_)
19
+ {}
20
+ end
21
+
22
+ def lint!
23
+ raise CanCamel::Linter::LintingError if (catch_args & catch_result).try(:any?)
24
+ end
25
+
26
+ def invoke!(args: {}, result: {})
27
+ args = my_slice(args, catch_args) if catch_args
28
+ args.merge! my_slice(result, catch_result) { |l, r, _k| r || l }
29
+ filter(**args)
30
+ end
31
+
32
+ def validates(*args)
33
+ CanCamel::Validators.validates(name, *args)
34
+ end
35
+
36
+ private
37
+
38
+ def my_slice(hash, args)
39
+ args.each_with_object({}) { |x, object| object[x] = hash[x] }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ module CanCamel::Filters
2
+ class CustomFilter
3
+ attr_reader :name
4
+
5
+ def initialize(name, lambda)
6
+ @name, @lambda = name, lambda
7
+ end
8
+
9
+ def invoke!(**args)
10
+ lambda.call(**args)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :lambda
16
+ end
17
+ end
@@ -1,16 +1,18 @@
1
1
  module CanCamel
2
2
  class GroupNode < Node
3
- belongs_to :parent, foreign_key: :parent_id, class_name: "CanCamel::ActionNode"
4
-
5
3
  validates_presence_of :parent_id
6
4
 
7
5
  def can?(**additional_params)
8
- condition.each_with_object(result.dup) do |(method, args), result|
6
+ condition.each_with_object(result.dup.merge(additional_params)) do |(method, args), result|
9
7
  args = args.symbolize_keys
10
- filtered = Filters.send(method, **args.merge(additional_params))
8
+ filtered = Filter.filters[method].invoke!(args: args.merge(additional_params), result: result)
11
9
  return unless filtered
12
10
  result.merge! filtered
13
11
  end || result
14
12
  end
13
+
14
+ def rank
15
+ 3
16
+ end
15
17
  end
16
18
  end
@@ -3,7 +3,8 @@ module CanCamel
3
3
  LintingError = Class.new(StandardError)
4
4
 
5
5
  def lint
6
- %i(lint_inheritance lint_nodes).reduce(true) { |base, x| base && send(x) }
6
+ Cache.reload! rescue return
7
+ %i(lint_nodes lint_filters).reduce(true) { |base, x| base && send(x) }
7
8
  end
8
9
 
9
10
  def lint!
@@ -16,11 +17,18 @@ module CanCamel
16
17
  %i(validate_node).reduce(true) { |base, x| base && send(x, node) }
17
18
  end
18
19
 
20
+ def lint_filters
21
+ CanCamel::Filter.filters.values.flatten.uniq.each { |filter| !filter.respond_to?(:lint!) || filter.lint! }
22
+ true
23
+ rescue CanCamel::Linter::LintingError
24
+ false
25
+ end
26
+
19
27
  private
20
28
 
21
29
  def validate_node(node)
22
30
  node.condition.each do |method, args|
23
- Validators.validate!(filter: method, args: args.symbolize_keys)
31
+ Validators.validate!(filter: method, args: args.symbolize_keys, path: node.path)
24
32
  end
25
33
  true
26
34
  rescue Validators::ValidationError, LintingError
@@ -30,21 +38,5 @@ module CanCamel
30
38
  def lint_nodes
31
39
  CanCamel::Node.all.reduce(true) { |base, x| base && lint_node(x) }
32
40
  end
33
-
34
- def lint_inheritance
35
- CanCamel::Node.with_parents.where(<<-SQL).empty?
36
- (
37
- #{TABLE_NAME}.type = 'CanCamel::ActionNode'
38
- AND
39
- parents.type != 'CanCamel::SubjectNode'
40
- )
41
- OR
42
- (
43
- #{TABLE_NAME}.type = 'CanCamel::GroupNode'
44
- AND
45
- parents.type != 'CanCamel::ActionNode'
46
- )
47
- SQL
48
- end
49
41
  end
50
42
  end
@@ -2,19 +2,43 @@ module CanCamel
2
2
  class Node < ActiveRecord::Base
3
3
  self.table_name = TABLE_NAME
4
4
  self.inheritance_column = 'type'
5
+
6
+ belongs_to :parent, foreign_key: :parent_id, class_name: "CanCamel::Node"
7
+ has_many :children, foreign_key: :parent_id, class_name: "CanCamel::Node"
8
+
9
+ has_many :actions, foreign_key: :parent_id, class_name: "CanCamel::ActionNode"
10
+ has_many :groups, foreign_key: :parent_id, class_name: "CanCamel::GroupNode"
11
+
5
12
  belongs_to :inherited_node, foreign_key: :inherit_id, class_name: "CanCamel::Node"
6
13
 
14
+ def cached_parent
15
+ Cache[path[1..-1]]
16
+ end
17
+
18
+ def rank
19
+ raise "inheriting invalid node"
20
+ end
21
+
22
+ def cached_inherited_node
23
+ return unless inherit_id
24
+ @inherited_path ||= inherited_node.path
25
+ Cache[@inherited_path]
26
+ end
27
+
7
28
  def self.with_parents
8
29
  joins("LEFT JOIN #{TABLE_NAME} AS parents ON #{TABLE_NAME}.parent_id = parents.id")
9
30
  end
10
31
 
11
32
  def inherit!(source = nil)
12
33
  return if inherited
34
+
35
+ raise 'inherit nodes only after cache built' unless Cache[path]
36
+
13
37
  @inherited = true
14
38
  return inherit_source! source if source
15
39
 
16
- inherit_source! parent if respond_to? :parent
17
- inherit_source! inherited_node
40
+ inherit_source! cached_parent
41
+ inherit_source! cached_inherited_node
18
42
  end
19
43
 
20
44
  validates! :inherited, absence: { message: "You should not save inherited nodes!" }
@@ -27,6 +51,12 @@ module CanCamel
27
51
  super.symbolize_keys
28
52
  end
29
53
 
54
+ attr_writer :path
55
+
56
+ def path
57
+ @path ||= parent ? [name] + parent.path : [name]
58
+ end
59
+
30
60
  private
31
61
 
32
62
  attr_reader :inherited
@@ -36,6 +66,12 @@ module CanCamel
36
66
 
37
67
  source.inherit!
38
68
 
69
+ Cache.children_of(source).each do |child|
70
+ next unless child.rank > rank
71
+ next if child == self
72
+ Cache.append child, path
73
+ end
74
+
39
75
  inherit_field(source, :description) { |x| self.description ||= x }
40
76
  inherit_field(source, :result) { |x| result.merge!(x) { |_k, l, _r| l } }
41
77
  inherit_field(source, :condition) { |x| self.condition = x.merge(condition) }
@@ -1,7 +1,9 @@
1
1
  module CanCamel
2
2
  class SubjectNode < Node
3
- has_many :actions, foreign_key: :parent_id, class_name: "CanCamel::ActionNode"
4
-
5
3
  validates :parent_id, absence: true
4
+
5
+ def rank
6
+ 1
7
+ end
6
8
  end
7
9
  end
@@ -2,6 +2,12 @@ module CanCamel::Validators
2
2
  ValidationError = Class.new(StandardError)
3
3
  UnknownFilter = Class.new(ValidationError)
4
4
 
5
+ extend ActiveSupport::Autoload
6
+ SUBMODULES = %i(GeneralValidators PathValidators)
7
+ SUBMODULES.each { |x| autoload x }
8
+ autoload :ValidatorsHelper
9
+ SUBMODULES.each { |x| extend const_get(x) }
10
+
5
11
  class <<self
6
12
  def included(base)
7
13
  base.define_singleton_method(:validates) { |*args| CanCamel::Validators.validates *args }
@@ -20,13 +26,13 @@ module CanCamel::Validators
20
26
  end
21
27
  end
22
28
 
23
- def validate!(filter:, args:)
29
+ def validate!(filter:, args:, path: nil)
24
30
  filter = filter.to_sym
25
31
  unless validators[filter]
26
- raise UnknownFilter unless CanCamel::Filters.respond_to? filter
32
+ raise UnknownFilter unless CanCamel::Filter.filters.include? filter
27
33
  return
28
34
  end
29
- validators[filter].each { |x| x.call(args) }
35
+ validators[filter].each { |x| x.call(path: path, **args) }
30
36
  end
31
37
 
32
38
  private
@@ -34,27 +40,5 @@ module CanCamel::Validators
34
40
  def validators
35
41
  @validators ||= {}
36
42
  end
37
-
38
- def presence(field:)
39
- raise ValidationError unless field.present?
40
- end
41
-
42
- def presence_of(fields:, args:, any: false)
43
- condition = fields.map { |x| args[x].present? }.reduce { |base, x| any ? (base || x) : (base && x) }
44
- return if condition
45
- raise ValidationError
46
- end
47
-
48
- def in(field:, array: [], empty: false)
49
- return if array.include? field
50
- return if empty && !field.present?
51
- raise ValidationError
52
- end
53
-
54
- def custom(field:, lambda:, empty: false)
55
- return if empty && !field.present?
56
- return if lambda.call(field)
57
- raise ValidationError
58
- end
59
43
  end
60
44
  end
@@ -0,0 +1,44 @@
1
+ module CanCamel::Validators
2
+ module GeneralValidators
3
+ def presence(field:)
4
+ raise ValidationError unless field.present?
5
+ end
6
+
7
+ def absence(field:)
8
+ raise ValidationError if field.present?
9
+ end
10
+
11
+ def presence_of(fields:, args:, any: false, only: false, none: false)
12
+ if [any, only, none].select(&:presence).count > 1
13
+ raise ValidationError, 'only one of [any, only, none] could be supplied to presence_of'
14
+ end
15
+
16
+ only = 0 if none
17
+ only = 1 if only && !only.is_a?(Fixnum)
18
+
19
+ fields_present = fields.select { |x| args[x].present? }
20
+
21
+ case
22
+ when only
23
+ return if fields_present.count == only
24
+ when any
25
+ return if fields_present.count > 0
26
+ else
27
+ return if fields_present.count == fields.count
28
+ end
29
+ raise ValidationError
30
+ end
31
+
32
+ def in(field:, array: [], empty: false)
33
+ return if array.include? field
34
+ return if empty && !field.present?
35
+ raise ValidationError
36
+ end
37
+
38
+ def custom(field:, lambda:, empty: false)
39
+ return if empty && !field.present?
40
+ return if lambda.call(field)
41
+ raise ValidationError
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ module CanCamel::Validators
2
+ module PathValidators
3
+ include ValidatorsHelper
4
+
5
+ def path(path:, action: nil, subject: nil, group: nil)
6
+ raise ValidationError unless action || subject || group
7
+ unless path && path.length == 3
8
+ raise ValidationError, 'trying to validate not a group node or invalid node structure'
9
+ end
10
+
11
+ validate_element(element: path[0], value: group) if group
12
+ validate_element(element: path[1], value: action) if action
13
+ validate_element(element: path[2], value: subject) if subject
14
+ end
15
+
16
+ alias_method :action, :path
17
+ alias_method :subject, :path
18
+ alias_method :group, :path
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module CanCamel::Validators
2
+ module ValidatorsHelper
3
+ def validate_element(element:, value:)
4
+ if value.is_a? Proc
5
+ raise ValidationError unless value.call element
6
+ return
7
+ end
8
+ raise ValidationError unless element.to_s == value.to_s
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module CanCamel
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,5 +1,4 @@
1
- # include custom ability filters
2
- # require 'can_camel/filters'
3
- # CanCamel::Filters.include AbilityFilters
1
+ # include custom validators
2
+ # CanCamel::Validators.extend AbilityFiltersValidators
4
3
  CanCamel::TABLE_NAME = "can_camel_nodes"
5
4
  CanCamel::GROUP_METHOD = :group
@@ -1,18 +1,14 @@
1
1
  class CreateCanCamelNodes < ActiveRecord::Migration
2
2
  def change
3
- reversible do |d|
4
- d.up { execute 'CREATE extension IF NOT EXISTS hstore;' }
5
- end
6
-
7
3
  create_table CanCamel::TABLE_NAME do |t|
8
4
  t.column :name, :string, index: true
9
5
  t.column :description, :text, null: true
10
6
  t.column :parent_id, :integer, null: true
11
7
  t.column :inherit_id, :integer, null: true
12
8
  t.column :type, :string
13
- t.column :override_fields, :string, array: true, default: []
14
- t.column :condition, :hstore, array: true, default: []
15
- t.column :result, :hstore, default: {}
9
+ t.column :override_fields, :json, default: []
10
+ t.column :condition, :json, default: {}
11
+ t.column :result, :json, default: {}
16
12
  end
17
13
  end
18
14
  end
@@ -4,6 +4,5 @@ class CanCamel::InstallGenerator < Rails::Generators::Base
4
4
  def install
5
5
  copy_file 'config/initializers/can_camel.rb'
6
6
  copy_file 'db/migrate/00000000000001_create_can_camel_nodes.rb'
7
- copy_file 'db/migrate/00000000000002_hstore_to_json.rb'
8
7
  end
9
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: can_camel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Smirnov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2015-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pg
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -54,16 +54,23 @@ files:
54
54
  - lib/can_camel/base.rb
55
55
  - lib/can_camel/cache.rb
56
56
  - lib/can_camel/concern_node.rb
57
+ - lib/can_camel/filter.rb
57
58
  - lib/can_camel/filters.rb
59
+ - lib/can_camel/filters/at_day.rb
60
+ - lib/can_camel/filters/at_time.rb
61
+ - lib/can_camel/filters/base.rb
62
+ - lib/can_camel/filters/custom_filter.rb
58
63
  - lib/can_camel/group_node.rb
59
64
  - lib/can_camel/linter.rb
60
65
  - lib/can_camel/node.rb
61
66
  - lib/can_camel/subject_node.rb
62
67
  - lib/can_camel/validators.rb
68
+ - lib/can_camel/validators/general_validators.rb
69
+ - lib/can_camel/validators/path_validators.rb
70
+ - lib/can_camel/validators/validators_helper.rb
63
71
  - lib/can_camel/version.rb
64
72
  - lib/generators/can_camel/config/initializers/can_camel.rb
65
73
  - lib/generators/can_camel/db/migrate/00000000000001_create_can_camel_nodes.rb
66
- - lib/generators/can_camel/db/migrate/00000000000002_hstore_to_json.rb
67
74
  - lib/generators/can_camel/install_generator.rb
68
75
  - lib/tasks/can_camel_tasks.rake
69
76
  homepage: https://github.com/JelF/can_camel
@@ -91,3 +98,4 @@ signing_key:
91
98
  specification_version: 4
92
99
  summary: CanCamel is a cancan style access controll library
93
100
  test_files: []
101
+ has_rdoc:
@@ -1,14 +0,0 @@
1
- class HstoreToJson < ActiveRecord::Migration
2
- def change
3
- unless ENV['RAILS_ENV'] == 'test' || ENV['FORCE_CAN_CAMEL_WIPE'] == 'true'
4
- puts "Attention! This migration will wipe can_camel data. Continue? (Y/n)"
5
- puts "Set FORCE_CAN_CAMEL_WIPE=true to automaticaly accept"
6
- res = STDIN.gets
7
- raise unless res =~ /\A[Yy]/
8
- end
9
- CanCamel::Node.delete_all
10
- remove_column CanCamel::TABLE_NAME, :condition, :hstore, array: true, default: []
11
- add_column CanCamel::TABLE_NAME, :condition, :json, default: {}
12
- CanCamel::Node.delete_all
13
- end
14
- end