Module: IAmICan::Dynamic

Extended by:
Dynamic
Included in:
Dynamic
Defined in:
lib/i_am_i_can/helpers/dynamic.rb

Instance Method Summary collapse

Instance Method Details

#assignment_helpersObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/i_am_i_can/helpers/dynamic.rb', line 48

def assignment_helpers
  #
  # Generate methods for each Content of Assignment
  #
  # Example for a subject model called User, which `has_and_belongs_to_many :stored_roles`.
  # You call the proc below by given contents [:role], then:
  #
  proc { |contents| contents.each do |content|
    content_cls = i_am_i_can.send("#{content}_class") rescue next
    _plural = '_' + content.to_s.pluralize
    __plural = send("_#{_plural}")

    # _stored_roles_exec
    #   Add / Remove (by passing action :cancel) roles to a user instance
    define_method "_#{_reflect_of(content)}_exec" do |action = :assign, instances = [ ], **conditions|
      collection, objects = send(_plural), [ ]
      records = conditions.present? ? content_cls.constantize.where(conditions) : [ ]

      case action
      when :assign  then collection << objects = (records + instances).uniq - collection
      when :cancel  then collection.destroy objects = (records + instances).uniq & collection
      when :replace then send("#{__plural}=", objects = (records + instances).uniq) # collection=
      end
      objects
    end
    #
    alias_method "_stored#{_plural}_exec", "_#{_reflect_of(content)}_exec"
  end }
end

#class_reflectionsObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/i_am_i_can/helpers/dynamic.rb', line 18

def class_reflections
  #
  # Extend each associated querying to a class method that returns ActiveRecord::Relation
  #
  # Suppose: in UserRole model,
  #   has_and_belongs_to_many :related_users
  #
  # It will do like this:
  #   def self.related_users
  #     User.with_stored_roles.where(user_roles: { id: self.ids })
  #   end
  #
  # Usage:
  #   UserRole.all.related_users
  #
  proc do
    %w[ subject role role_group permission ].each do |k|
      next if _reflect_of(k).blank?
      define_singleton_method _reflect_of(k) do
        model = i_am_i_can.send("#{k}_model")
        raise NoMethodError unless (reflect_name = model._reflect_of(i_am_i_can.act))

        model.send("with_#{reflect_name}").where(
            self.name.underscore.pluralize => { id: self.ids }
        )
      end
    end
  end
end

#definition_helpersObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/i_am_i_can/helpers/dynamic.rb', line 78

def definition_helpers
  #
  # Generate class methods for each Content of Definition
  #
  # Example for a subject model called User,
  #   which `has_many_temporary_roles` and `has_and_belongs_to_many :stored_roles`.
  # You call the proc below by given contents [:role], then:
  #
  proc { |contents| contents.each do |content|
    content_cls = i_am_i_can.send("#{content}_class") rescue next
    _plural = '_' + content.to_s.pluralize

    # _create_roles
    #    Define and store roles of Subject
    define_singleton_method "_create#{_plural}" do |objects|
      # Role.create([{ name: .. }]).reject { the roles that validation failed }
      content_cls.constantize.create(objects)
          .reject {|record| record.new_record? }
    end
  end }
end

#scopesObject



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/i_am_i_can/helpers/dynamic.rb', line 5

def scopes
  #
  # Generate scopes of each specified i_am_i_can association
  #
  # scope :with_stored_roles, -> { includes(:stored_roles) }
  #
  proc do |keys|
    keys.each do |k|
      scope :"with_#{_reflect_of(k)}", ->  { includes(_reflect_of(k)) }
    end
  end
end