1+ module Oxidizer
2+ module Assignable
3+ extend ActiveSupport ::Concern
4+
5+ included do
6+ class_attribute :model , :parent_model , :context_method_name
7+
8+ before_action :assign_parent_collection , if : :has_parent_model?
9+ before_action :assign_parent_member , if : :has_parent_model?
10+ before_action :assign_collection
11+ before_action :assign_member
12+ end
13+
14+ def assign_collection
15+ instance_variable_set "@#{ model . model_name . plural } " , model_scope
16+ end
17+
18+ def assign_parent_collection
19+ instance_variable_set "@#{ parent_model . model_name . plural } " , parent_model_scope
20+ end
21+
22+ def model_scope
23+ if has_parent_model?
24+ parent_model_instance . association ( model . model_name . collection )
25+ elsif has_assignable_context?
26+ assignable_context . association ( model . model_name . collection ) . scope
27+ else
28+ model . scope_for_association
29+ end
30+ end
31+
32+ def parent_model_scope
33+ if has_assignable_context?
34+ assignable_context . association ( parent_model . model_name . collection )
35+ else
36+ parent_model . scope_for_association
37+ end
38+ end
39+
40+ def parent_model_instance
41+ parent_model_scope . find ( params . fetch ( parent_model_param_key ) )
42+ end
43+
44+ def assign_parent_member
45+ instance_variable_set "@#{ parent_model . model_name . singular } " , parent_model_instance
46+ end
47+
48+ def has_parent_model?
49+ parent_model . present?
50+ end
51+
52+ def assign_member
53+ instance_variable_set "@#{ model . model_name . singular } " , model_instance
54+ end
55+
56+ def model_instance
57+ if member?
58+ model_scope . find params . fetch ( model_param_key )
59+ else
60+ model_scope . build
61+ end
62+ end
63+
64+ def member?
65+ params . key? model_param_key
66+ end
67+
68+ def model_param_key
69+ :id
70+ end
71+
72+ def parent_model_param_key
73+ "#{ parent_model . model_name . singular } _id" . to_sym
74+ end
75+
76+ def assignable_context
77+ self . send self . class . context_method_name
78+ end
79+
80+ def has_assignable_context?
81+ if self . class . context_method_name
82+ self . respond_to? self . class . context_method_name
83+ end
84+ end
85+
86+ class_methods do
87+ def assign ( scope , through : nil , from : nil )
88+ self . model = Assignable . find_scope scope
89+ self . parent_model = Assignable . find_scope through
90+ self . context_method_name = from
91+ end
92+ end
93+
94+ def self . find_scope ( name )
95+ name . to_s . singularize . camelize . constantize if name
96+ end
97+ end
98+ end
0 commit comments