Module: ActionPlugin::Mixin::ClassMethods

Defined in:
lib/action_plugin/mixin.rb

Instance Method Summary collapse

Instance Method Details

#action_plugin(subject_type, action_type, target_type) ⇒ Object



33
34
35
36
# File 'lib/action_plugin/mixin.rb', line 33

def action_plugin(subject_type, action_type, target_type)
  initialize_params(subject_type, action_type, target_type)
  define_relations
end

#define_relationsObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/action_plugin/mixin.rb', line 38

def define_relations
  options                  = @options
  actioning_target_actions = [@actioning, @target, :actions].join('_').to_sym
  actioning_targets        = [@actioning, @target].join('_').pluralize.to_sym
  actioned_subject_actions = [@actioned, @subject, :actions].join('_').to_sym
  actioned_subjects        = [@actioned, @subject].join('_').pluralize.to_sym
  has_many_scope           = -> { where(subject_type: options[:subject_type],
    action_type: options[:action_type], target_type: options[:target_type])
  }

  # like following_user_actions
  @subject_class.send(:has_many, actioning_target_actions, has_many_scope,
                      class_name: "Action", foreign_key: "subject_id")
  # like following_users
  @subject_class.send(:has_many, actioning_targets, through: actioning_target_actions,
                      source: :target, source_type: @target_type)

  # like followed_user_actions
  @target_class.send(:has_many, actioned_subject_actions, has_many_scope,
                      class_name: "Action", foreign_key: "target_id")

  # like followed_users
  @target_class.send(:has_many, actioned_subjects, through: actioned_subject_actions,
                      source: :subject, source_type: @subject_type)
  define_some_methods
end

#define_some_methodsObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/action_plugin/mixin.rb', line 65

def define_some_methods
  options            = @options
  action_target      = [@action_type, @target].join("_")
  unaction_target    = "un#{action_target}"
  action_target_mark = "#{action_target}?"

  # define_method like follow_user
  @subject_class.send(:define_method, action_target) do |target_or_id|
    target_id = target_or_id.is_a?(options[:target_class]) ? target_or_id.id : target_or_id
    Action.find_or_create_by( subject_id: self.id, subject_type: self.class.name,
                              action_type: options[:action_type], target_id: target_id,
                              target_type: options[:target_type]
                            )
  end

  # define_method like follow_user?
  @subject_class.send(:define_method, action_target_mark) do |target_or_id|
    target_id = target_or_id.is_a?(options[:target_class]) ? target_or_id.id : target_or_id
    action    = find_action(subject: self, action_type: options[:action_type],
                            target_id: target_id, target_type: options[:target_type]
                           )
    action.present?
  end

  # define_method like unfollow_user
  @subject_class.send(:define_method, unaction_target) do |target_or_id|
    target_id = target_or_id.is_a?(options[:target_class]) ? target_or_id.id : target_or_id
    action    = find_action(subject: self, action_type: options[:action_type],
                            target_id: target_id, target_type: options[:target_type]
                           )
    action.destroy
  end

  @subject_class.send(:define_method, "find_action") do |opts = {}|
    opts   = validate_opts(opts)
    action = Action.find_by(format_opts(opts))
    action
  end
end

#initialize_params(subject_type, action_type, target_type) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/action_plugin/mixin.rb', line 18

def initialize_params(subject_type, action_type, target_type)
  @subject_type  = subject_type.to_s.classify
  @action_type   = action_type.to_s
  @actioning     = "#{@action_type}ing"
  @actioned      = "#{@action_type}ed"
  @target_type   = target_type.to_s.classify
  @subject_class = @subject_type.constantize
  @target_class  = @target_type.constantize
  @subject       = @subject_type.downcase
  @target        = @target_type.downcase
  @options       = { subject_type: @subject_type, action_type: @action_type,
    target_type: @target_type, target_class: @target_class
  }
end