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
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
104
105
106
107
108
109
110
111
112
|
# File 'lib/current_scope/parent_chain.rb', line 51
def current_scope_parent(association_name)
reflection = reflect_on_association(association_name)
if reflection.nil?
raise ConfigurationError,
"#{name}.current_scope_parent(#{association_name.inspect}) names an " \
"association that does not exist. Declare `belongs_to " \
"#{association_name.inspect}` first, or name the association that " \
"reaches the record scoped grants are held on."
end
unless reflection.belongs_to?
raise ConfigurationError,
"#{name}.current_scope_parent(#{association_name.inspect}) must name a " \
"belongs_to association — #{association_name.inspect} is a " \
"#{reflection.macro}. A scoped grant is held on ONE parent record, so " \
"the chain walks upward one owner at a time. Declare it on the CHILD " \
"instead — `current_scope_parent` in #{reflection.klass.name} — so a " \
"grant held here reaches its #{association_name}."
end
if reflection.polymorphic?
raise ConfigurationError,
"#{name}.current_scope_parent(#{association_name.inspect}) names a " \
"polymorphic belongs_to, which is not supported: the parent's class is " \
"not knowable without loading every candidate row, so scope_for could " \
"not build its query. Either name a concrete belongs_to if this model " \
"has one, or keep this model flat and grant on it directly."
end
if reflection.scope
raise ConfigurationError,
"#{name}.current_scope_parent(#{association_name.inspect}) names a SCOPED " \
"belongs_to. The per-record walk would apply that scope and the collection " \
"query would not, so the gate and the list would disagree about the same " \
"record. Declare an unscoped belongs_to for the chain."
end
if self != base_class
raise ConfigurationError,
"#{name}.current_scope_parent(#{association_name.inspect}) is declared on " \
"an STI subclass. Declare it on #{base_class.name} instead: scoped grants " \
"store the base class, and the collection query is built from it, so a " \
"subclass-only chain would open records the list could never show."
end
self.current_scope_parent_association = association_name.to_sym
CurrentScope::ParentChain.register(self)
end
|